函數設計注意點:
耦合性:儘量不要使用全局變量;儘量不要改變函數中接收的可變實參的值;避免直接更改另一個模塊文件中的變量。
聚合性:每個函數都有一個單一的,統一的目標,並且函數儘可能的小。
Python的函數是一個對象,函數對象可以賦值給其他名字,傳遞給其他函數,嵌入到數據結構。而對於用於def語句中的名稱,它只是當前作用域的一個變量賦值,def運行之後,該名字指向了函數對象,我們可以把該對象賦給其他對象,同時我們也可以給這個函數名賦予其他對象。
>>> def echo(message): #給變量echo賦予一個函數對象
... print(message)
...
>>> echo
<function echo at 0xb70760ac>
>>> x=echo #把函數對象賦予其他變量
>>> x('hello world')
hello world
>>> echo=5 #給變量echo賦予一個整數對象
>>> echo
5
函數內省
因爲函數也是對象,所以我們也可以像一個類一樣,通過.引用來查看它的屬性的值;而通過在引用dir方法,可以深入探索下一層的細節。
>>> def fun(a):
... print(a)
...
>>> dir(fun)
['__annotations__', '__call__', '__class__', '__closure__', '__code__',... , '__subclasshook__']
>>> fun.__code__
<code object fun at 0xb71532a0, file "<stdin>", line 1>
>>> dir(fun.__code__)
['__class__', ..., 'co_argcount', ..., 'co_varnames'] #注意比較長的是兩個_,因爲是文件名的連接,所以中間是一個短線
>>> fun.__code__.co_varnames
('a',)
>>> fun.__code__.co_argcount
1
函數屬性
除了上面我們查看到的函數屬性,我們也可以通過手動添加一個新的屬性。
>>> fun.count=0 #手動添加屬性count,
>>> dir(fun) #通過dir方式,你可以查看count已經添加到fun的屬性中
['__annotations__', ...,'__sizeof__', '__str__', '__subclasshook__', 'count']
函數註解
註解信息:與函數的參數和結果相關的任意的用戶定義的數據。它是可選的,出現的時候直接附加到函數對象的__annotations__,註解它編寫在def頭部行,所以我們只有在定義函數的時候才能對它進行設置。我們只對變量和函數返回值進行註釋。
參數的註釋 :在參數後面加個冒號和註釋信息。如果你想對參數設置默認值的話,它處在註釋之後。
返回值的註釋 :在參數列表之後冒號之前加一個->後面是標註信息
>>> def fun(a:'spam'=4, b:(1,10)=5, c:float=6) -> int:
... return a+b+c
...
>>> fun.__annotations__
{'a': 'spam', 'c': <class 'float'>, 'b': (1, 10), 'return': <class 'int'>}
lambda
lambda表達式:一個或多個參數,緊接着一個冒號,之後是表達式。lambda argument1,argument2,...argument3:expression using arguments
lambda引入的本地作用域更像一個嵌套的def語句,將會自動從上層函數中,模塊中以及內置作用域中(通過LEGB法則)查變量
>>> def knights():
... title ='sir'
... action =(lambda x='fee':title+x) #默認值方式,它把表達式作爲返回值
... return action
...
>>> act=knights()
>>> act('hello')
'sirhello'
在序列中映射函數:map
map 函數會對一個序列對象中的每一個元數應用被傳入的函數,並且返回一個包含了所有調用結果的列表。因爲它第一個參數期待函數對象,所以常與lambda配合
>>> map((lambda x:x+3),(1,2,3)) #僅僅得到的是函數對象
<map object at 0xb707544c>
>>> list(map((lambda x:x+3),(1,2,3)))
[4, 5, 6]
>>> list(map(pow,[1,2,3],[2,3,4])) #賦予一個N參數的函數用於N序列,並行處理序列,並返回結果
[1, 8, 81]
filter 和 reduce
filter 基於某一個測試函數過濾一些元數
reduce 對每對元素都應用函數並運行到最後結果
>>> list(filter((lambda x: x>0),range(-5,5))) #序列中大於0的選出來
[1, 2, 3, 4]
>>> from functools import reduce
>>> reduce((lambda x, y:x+y),[1,2,3,4])
10