函數是Python
爲了代碼最大程度的重用和最小化代碼冗餘而提供的最基本的程序結構。python
函數式:將某功能代碼封裝到函數中,往後便無需重複編寫,僅調用函數便可git
面向對象:對函數進行分類和封裝,讓開發「更快更好更強...」express
函數式編程最重要的是加強代碼的重用性和可讀性編程
建立的函數語法bash
def 函數名(參數): ... 函數體 ... 返回值
簡單的實例app
# x爲函數的參數 >>> def num(x): ... print(x) ... # 123456等於x >>> num("123456") 123456
函數的返回值須要使用到return
這個關鍵字,返回值主要是用來接受函數的執行結果函數式編程
>>> def re(): ... if 1==1: ... return True ... else: ... return False ... >>> re() True
函數return後面是什麼值,re就返回什麼值,若是沒有指定return返回值,那麼會返回一個默認的參數None
函數
在函數中,當return
執行完成以後,return
後面的代碼是不會被執行的測試
>>> def ret(): ... print("123") ... return True ... print("abc") ... >>> ret() 123 True
傳入參數的值是按照順序依次賦值過去的。ui
代碼
# x==形式參數,形式參數有幾個,那麼實際參數就要傳幾個,默認參數除外 def ret(x): print(x) # "Hello Word"實際參數 print(ret("Hello Word"))
執行結果
Hello Word
如圖所示:
ret小括號內的值會被傳入到函數ret裏面都能作x的值,結果差很少就是print("Hello Word")
def email(mail): import smtplib from email.mime.text import MIMEText from email.utils import formataddr msg = MIMEText('郵件內容', 'plain', 'utf-8') msg['From'] = formataddr(["測試",'asdasd@126.com']) msg['To'] = formataddr(["走人",'asdasdasd@163.com']) msg['Subject'] = "主題" server = smtplib.SMTP("smtp.126.com", 25) server.login("wdfgfghfgh@126.com", "123456") server.sendmail('asdasdas@126.com', [mail,], msg.as_string()) server.quit() email("6087414@qq.com")
當執行這個腳本的時候會給郵箱6087414@qq.com
發送郵件。
注:上面的郵箱地址等都是隨便寫的,請自行更改
>>> def ret(a,b,c): ... print(a,"a") ... print(b,"b") ... print(c,"c") ... >>> ret(b="bbb",a="aaa",c="ccc") aaa a bbb b ccc c
默認狀況在再函數ret括號內若是要輸入函數參數的值,是要按照順序來的,可是若是在ret括號內製定的參數的值,那麼就不須要按照順序來了。
若是咱們在建立函數的時候給函數定義了值,那麼在調用函數的時候若是不填寫值程序就會報錯:
>>> def ret(x): ... print(x) ... >>> ret() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: ret() missing 1 required positional argument: 'x'
若是要解決這個問題就能夠給函數的值指定一個默認值,指定函數的默認值須要在def
這一行指定,制定以後,當調用這個函數的時候就不須要輸入函數值了。
>>> def ret(x="Hello Word"): ... print(x) ... >>> ret() Hello Word # 若是值指定默認值,那麼實際參數替換掉形式參數 >>> ret("Pythoner") Pythoner
若是給函數建立了默認值,那麼有默認值的這個參數必須在最後面定義,不可以在沒有默認參數的值的前面。
動態參數把接收過來的實際參數看成一個元組,每個參數都是元組中的一個元素。
第一種動態參數
定義第一種動態參數須要在參數前面加上一個*
號
>>> def ret(*args): ... print(args,type(args)) ... >>> ret(11,22,33) (11, 22, 33) <class 'tuple'>
第二種動態參數
定義第二種動態參數須要在參數前面加上兩個*
號,給參數傳參的時候是一個key對應一個value的,至關於一個字典的鍵值對,並且返回的類型就是字典類型。
使用兩個星號能夠將參數收集到一個字典中,參數的名字是字典的鍵,對應參數的值是字典的值。
>>> def ret(**kwargs): ... print(kwargs,type(kwargs)) ... >>> ret(k1=123,k2=456) {'k1': 123, 'k2': 456} <class 'dict'>
第三種動態參數
第三種又稱爲萬能的動態參數,以下實例:
>>> def ret(*args,**kwargs): ... print(args,type(args)) ... print(kwargs,type(kwargs)) ... >>> ret(11,222,333,k1=111,k2=222) (11, 222, 333) <class 'tuple'> {'k1': 111, 'k2': 222} <class 'dict'>
字典小例子:
>>> def arg(**kwargs): ... print(kwargs,type(kwargs)) ... >>> dic = {"k1":123,"k2":456} >>> arg(k1=dic) {'k1': {'k1': 123, 'k2': 456}} <class 'dict'> >>> arg(**dic) {'k1': 123, 'k2': 456} <class 'dict'>
若是不想在函數內部修改參數值而影響到外部對象的值,咱們可使用切片的方式進行參數的傳遞:
#!/use/bin/env python L = ['a', 'b'] def changer(L): L[0] = 0 print(L) changer(L) """ ['a', 'b'] [0, 'b'] """ # changer(L[:]) """ ['a', 'b'] ['a', 'b'] """ print(L)
In [2]: def f(a, b, c, d): print(a, b, c, d) In [3]: args = (1, 2) In [4]: args += (3, 4) In [5]: f(*args) 1 2 3 4
又或者使用
def f(a, b, c, d): print(a, b, c, d) args = {'a': 1, 'b': 2, 'c': 3, 'd': 4} f(**args)
在函數調用中: 位置參數 --》 關鍵字參數 --》元組形式--》字典形式
在函數頭部: 通常參數--》默認參數--》元組形式--》字典形式
def func(name, age=None, *args, **kwargs): print(name, age, args, kwargs) func('ansheng', 18, *(1, 2, 3), **{'blog': 'blog.ansheng.me'})
簡單的理解全局變量和變量,全局變量能夠理解爲在當前這個文件內定義的變量,局部變量則是在函數內定義的變量,以下例:
# qa # 全局變量 n1 = 1 def num(): # 局部變量 n2 = 2 print(n1) print(n2) num()
輸出的結果
C:\Python35\python.exe F:/Python_code/sublime/Day05/def.py 1 2
定義的全局變量均可以在函數內調用,可是不能再函數內修改,局部變量在也不可以直接調用,若是要在函數內修改全局變量,那麼就須要用到關鍵字``
n1 = 1 def num(): n2 = 2 global n1 n1 = 3 print(n1) print(n2) num()
執行結果
C:\Python35\python.exe F:/Python_code/sublime/Day05/def.py 3 2
nonlocal
是用來修改嵌套做用域中的變量,相似於global
同樣,只須要在嵌套函數中聲明變量名便可,可是這個變量名是必須已經存在的不然就會報錯,若是要修改的變量在做用域中查找不到,那麼不會繼續到全局或內置做用域中查找。
In [1]: def func1(arg1): ...: n = arg1 ...: print(n) ...: def func2(): ...: nonlocal n ...: n += 1 ...: func2() ...: print(n) ...: In [2]: func1(10) 10 11
Lambda(Lambda expressions)表達式是用lambda關鍵字建立的匿名函數,Lambda函數能夠用於任何須要函數對象的地方,在語法上,它們被侷限於只能有一個單獨的表達式。
使用Lambda
表達式建立函數
>>> f = lambda x,y : x + y >>> f(1,2) 3
使用def建立函數
>>> def f(x,y): ... return x + y ... >>> f(1,2) 3
對於比較簡單的函數咱們就能夠經過lambda來建立,它的的好處是縮短行數。
lambda建立的函數和def建立的函數對應關係如圖所示:
def action(x): return (lambda y: x + y) act = action(99) print(act) result = act(2) print(result)
輸出爲:
<function action.<locals>.<lambda> at 0x1021e6400> 101
lambda
也可以獲取到任意上層lambda
中的變量名:
action = lambda x: (lambda y: x + y) act = action(99) print(act) result = act(3) print(result)
輸出爲:
<function <lambda>.<locals>.<lambda> at 0x1029e6400> 102
簡述普通參數、指定參數、默認參數、動態參數的區別
普通參數便是用戶在調用函數是填入的參數,且參數位置必須與參數保持一致。
指定參數即在用戶調用函數的時候不須要按照函數中參數的位置中所填寫,指定參數是須要制定參數對應的值。
默認參數能夠寫在定義參數的後面,若是用戶調用函數是沒有制定參數,那麼就會用默認參數,若是用戶指定了參數,那麼用戶指定的參數就會代替默認參數。
動態參數能夠接受用戶輸入的任何參數,包括字典、列表、元組等數據類型。
計算傳入字符串中數字、字母、空格以及其餘的個數
def var(s): all_num = 0 spance_num = 0 digit_num = 0 others_num = 0 for i in s: # 檢測數字 if i.isdigit(): digit_num += 1 # 檢測空格 elif i.isspace(): spance_num += 1 # 檢測字母 elif i.isalpha(): all_num += 1 else: # 其餘 others_num += 1 return ("字母:",all_num,"空格:",spance_num,"數字",digit_num,"其餘字符",others_num) num = var("21323 asd*%^*^% &*213asdasdasda sdasdasd") print(num)
執行結果
C:\Python35\python.exe F:/Python_code/sublime/operation/Day05/c.py ('字母:', 21, '空格:', 3, '數字', 8, '其餘字符', 8)
寫函數,判斷用戶傳入的對象(字符串、列表、元組)長度是否大於5,若是大於5就返回True,若是小於5就返回False
# 定義一個函數num def num(x): # 判斷函數的值若是長度大於5就返回True if len(x) > 5: return True # 不然就返回False else: return False ret = num(["asd","asdasd","asdasd","asdasd"]) print(ret) ret = num("asdasdasd") print(ret)
寫函數,檢查用戶傳入的對象(字符串、列表、元組)的每個元素是否含有空內容,若是有空就返回False
# 定義一個函數num def num(x): # 循環輸出num內的全部內容 for n in x: # 數據類型轉換爲字符串 n = str(n) # 若是有空格就返回False if n.isspace(): return False ret = num(" ") print(ret) ret = num("asdasd") print(ret) ret = num(["asd","312",123," "]) print(ret)
寫函數,檢查傳入列表的長度,若是大於2,那麼僅保留前兩個長度的內容,並將新內容返回給調用者。
def num(x): # 若是列表中的長度大於2,那麼就輸出列表前兩個內容,不然就返回一個空 if len(x) > 2: return x[:2] else: return "" print(num(["11","22","33"])) print(num(["33"]))
寫函數,檢查獲取傳入列表或元組對象的全部奇數位索引對應的元素,並將其做爲新列表返回給調用者。
def num(x): # 定義一個空列表用於接收奇數位的元素 resule = [] # 循環輸出列表中的全部元素值 for n in range(len(x)): # 若是列表中的位置爲奇數就把值添加到resule列表中 if n % 2 == 1: resule.append(x[n]) # 然會resule列表中的內容 return resule ret = num([11,22,33,44,55,66]) print(ret)
寫函數,檢查傳入字典的每個value的長度,若是大於2,那麼僅保留前兩個長度的內容,並將新內容返回給調用者。
dic = {"k1": "v1v1", "k2": [1111,22,33,44]}
PS:字典中的value只能是字符串或列表
代碼
def dictt(x): # 循環字典中全部的key for k in x.keys(): # 若是字典中k對應的元素是字符串類型就下面的判斷 if type(x[k]) == str: # 若是元素的長度大於2 if len(x[k]) > 2: # 那麼就讓這個元素從新賦值,新的值只保留原來值的前兩個 x[k]=x[k][0:2] # 若是字典中k對應的元素類型是列表,就進入下面的判斷 elif type(x[k]) == list: # 先把列表中的值所有for循環 for i in x[k]: # 把元素轉換爲字符串 string = str(i) # 若是元素的長度大於2 if len(string) > 2: # 獲取元素的索引值 num = x[k].index(i) # 先把這個元素給刪除 x[k].pop(x[k].index(i)) # 而後再添加一個新的元素,新元素的只保留原來元素的前兩個 x[k].insert(num,string[:2]) # 把結果return出來 return dic ret = dictt(dic) print(ret)
執行結果
C:\Python35\python.exe F:/Python_code/sublime/operation/Day05/h.py {'k1': 'v1', 'k2': ['11', 22, 33, 44]}