十一、函數 Python中函數以def定義,用於實現某種功能,若是某段代碼被多處使用,不妨將它定義成一個函數,或是它用於實現特定的功能,也可以將它定義成一個函數; 一個函數func(),func為函數名,是這個函數引用(指向函數的地址);而加上括弧func()則表示執行這個函數; 在函數中定義的變數 ...
十一、函數
Python中函數以def定義,用於實現某種功能,若是某段代碼被多處使用,不妨將它定義成一個函數,或是它用於實現特定的功能,也可以將它定義成一個函數;
一個函數func(),func為函數名,是這個函數引用(指向函數的地址);而加上括弧func()則表示執行這個函數;
在函數中定義的變數為局部變數,在函數體為不可引用它(在for迴圈中定義的變數,for迴圈體之外可引用);
函數的動態參數func(*args1, **args2),*args1會將傳進來的參數以元組的形式存在args1中,**args2會將以特定形式傳進來的參數以字典的形式存在args2中,例如:func(a, b, c, name = 'Jom', age = '17'),其中a、b、c為變數,name和age為key,等號後面的作為value;
在文件中函數不會被運行,Python只是去載入它,除非它被引用執行;Python文件有一個系統變數為“__name__”,預設值為當前文件名,但是被執行的文件預設值為“__main__”,所以可以使用"if '__name' == '__main__':"作為文件的執行入口;
若是這個函數沒有使用return指定這個函數的返回值,那麼這個函數的返回值預設為None。
>>> def func(*args1, **args2): # 動態參數指不用指定參數參數個數和各個參數的形參名
print(args1)
print(args2)
print(args1[2])
print(args2['name'])
>>> func
<function func at 0x0000000003450598>
>>> result = func(1, 2, 3, name = 'Jom', age = '17')
(1, 2, 3)
{'age': '17', 'name': 'Jom'}
3
Jom
>>> print(result) # 沒有使用return指定返回值
None
十二、迭代器與生成器
迭代器:
迭代器用於訪問集合中的元素,使用迭代器不需要提前準備好要迭代的所有元素,只有迭代到某個元素時才會計算該元素,這個元素之前或之後都是沒有的,因為迭代器這個特點,它遍歷集合元素占用的記憶體很少,適用於訪問一些特別大的甚至是無限的集合;
迭代器迭代元素時使用__next__()方法不斷地去訪問下一個元素,只能“前進”,不能“後退”,也不能通過下標等去訪問某個特定的元素;
當訪問完集合後,這個迭代器就“完了”,要想再遍歷這個集合,就要新建一個迭代器了。
生成器:
如果一個函數被調用時返回了一個迭代器,那麼這個函數就叫做生成器;如果一個函數中含有yield語法,那麼這個函數也是生成器;
yield語法的特點:當含有yield語法的函數被調用後,執行yield後,就會中斷這個函數,繼續執行這個函數之後的代碼,當下一次這個函數再被調用時,會從這個函數的上次執行的yield之後的代碼開始執行。
>>> def generator(): n = 3 while n > 0: yield 'hello python!' # 含有yield,這個函數即為生成器,每次生成一個字元串“hello python!” n -= 1 >>> iterator = generator() # 返回一個迭代器 >>> iterator.__next__() 'hello python!' >>> iterator.__next__() 'hello python!' >>> iterator.__next__() 'hello python!' >>> iterator.__next__() # 訪問完後就“沒有了”,這個迭代器也不能再用了 Traceback (most recent call last): File "<pyshell#13>", line 1, in <module> iterator.__next__() StopIteration >>>
十三、裝飾器
裝飾器的作用就是為已存在的對象添加額外的功能,特點在於不用改變原先的代碼即可擴展功能;
一個對象可以被多個裝飾器裝飾,裝飾器也可以帶參數裝飾(如下例中可以這樣@decorator(func1, func2),當然參數也是函數名,而hello就會被作為裝飾器返回值所代表的函數(inner())的參數了,不再直接是decorator()的參數了(decorator()的參數已被func1和func2占用了)),這裡就只展示裝飾器基本原理和流程。
def decorator(func): print('hello python!') def inner(name): print('hello, my friend') func(name) # func即為hello()函數 return inner @decorator # 裝飾器用@表示,函數decorator()裝飾函數hello() def hello(name): print('hello %s!' % name) hello('Jom') # 執行函數 -------------------------------------------------------------- hello python! hello, my friend hello Jom!
在載入裝飾器時,也就是載入到@符時,會運行一次裝飾器(也就是被@修飾的函數),它的返回值會替代被修飾的函數地址,而被修飾的函數的地址以裝飾器函數參數的形式傳進了裝飾器。示例中:載入到@decorator時,運行了一次decorator()函數,這時函數hello()把函數名(也就是函數地址hello)作為裝飾器參數func傳了進去,decorator()執行完後返回函數inner()的函數地址(這個函數地址替代了函數hello()的函數地址),執行hello('Jom')時,就會執行替換後的函數,即inner('Jom'),然後就會去執行inner()函數內的內容。