一等對象html
普通函數 & 高階函數python
可調用對象 & 自定義可調用類型git
函數內省github
函數註釋編程
python高級——目錄數據結構
文中代碼均放在github上:https://github.com/ampeeg/cnblogs/tree/master/python高級閉包
''' 在python中,"一等對象"指的是知足下述條件的程序實體: (1)在運行時建立 (2)能賦值給變量或數據結構中的元素 (3)能做爲參數傳給函數 (4)能做爲函數的返回結果 整數、字符串和字典都是一等對象。在面向對象編程中,函數也是對象,並知足以上條件,因此函數也是一等對象,稱爲"一等函數" ''' if __name__ == "__main__": # 函數的一等性質 def foo(n): '''returns n!''' return 1 if n < 2 else n * foo(n-1) print(foo(5)) # 120 my_foo = foo print(my_foo) # <function foo at 0x1010e3f28> 能賦值給變量 print(list(map(my_foo, range(6)))) # [1, 1, 2, 6, 24, 120] 能賦值給函數 def foo2(): return foo my_foo2 = foo2() print(my_foo2(5)) # 120 可做爲函數的返回結果 |
''' 咱們通常將函數分爲"普通函數"和"高階函數",接受函數爲參數的函數爲高階函數,其他爲普通函數 普通函數你們再熟悉不過,本文不講,主要講一下map、filter、reduce三個高階函數 ''' if __name__ == "__main__": # map第一個參數接受一個函數,並將這個函數做用於後面可迭代對象的每個元素中 l = map(lambda x : x ** 2, range(11)) # 返回的是生成器類型 print(list(l)) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100] w = map(str.upper, 'asfafasfasfaf') print(list(w)) # ['A', 'S', 'F', 'A', 'F', 'A', 'S', 'F', 'A', 'S', 'F', 'A', 'F'] # filter第一個參數也接受函數,並返回全部知足該函數的元素 l = filter(lambda n: n % 2, range(10)) # 返回n % 2爲真的數,就是奇數 l2 = filter(lambda n: n % 2 ==0, range(10)) # 返回偶數 print(list(l)) # [1, 3, 5, 7, 9] print(list(l2)) # [0, 2, 4, 6, 8] # reduce 從python3開始,reduce放在functools中 # reduce將某個操做連續應用到序列元素上,即其會將前一步的結果繼續應用到下一個元素上 from functools import reduce s = reduce(lambda x,y: x + y, range(101)) print(s) # 5050 對1到100求和 |
''' 咱們在使用函數或者實例化對象的時候會用到括號(即()),這個括號其實是調用運算符,python裏面有7中可調用對象: 一、用戶定義的函數 def和lambda建立 二、內置函數 使用C語言實現的函數,如len或time.strftime 三、內置方法 使用C語言實現的方法,如dict.get 四、方法 在類的定義體中定義的函數 五、類 調用類時其實首先運行的是__new__方法,而後運行__init__方法。這裏頗有意思,自定義類中其實沒有重寫__new__方法, 而是調用的超類的__new__方法,若是查看源代碼的實現邏輯,相信你會有新的發現,這裏不作討論。 六、類的實例 若是類定義了__call__方法,那麼它的實例能夠做爲函數調用 七、生長器函數 使用yield關鍵字的函數或方法。 ''' if __name__ == "__main__": # 建立一個自定義可調用類 class Foo(): def __init__(self): self.name = "Foo" def __call__(self, *args, **kwargs): print("調用__call__") Foo()() # 輸出:調用__call__ # 以上使用 Foo()() 這種寫法看上去頗有意思。首先,Foo()會建立一個Foo實例,調用__init__構造方法,; 而後使用實例(),此時 # 調用__call__方法 |
''' 函數內省咱們經過例子來看 ''' if __name__ == "__main__": # 先建立一個函數 def foo(n): ''':returns n!''' return 1 if n<2 else n*foo(n-1) print(foo.__doc__) # :returns n! __doc__裏面存儲了註釋內容 # 看看這個函數中有多少屬性 print(dir(foo)) ''' ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] ''' # 下表對一些屬性作了說明
|
''' 函數註解很簡單,用下面例子簡單講解便可明瞭 ''' if __name__ == "__main__": def foo(num: int, step: 'int 間隔(大於0小於num)'=1) -> int: ''':returns 求num的階乘,能夠設置步長''' # 這裏的註釋存儲在__doc__中 return num if num <= step else num * foo(num-step,step) print(foo(5)) # 120 (5*4*3*2*1) print(foo(5, 2)) # 15 (5*3) # 函數聲明中的各個參數能夠在冒號(:)以後增長註釋,該註釋能夠直接寫參數類型,也能夠寫字符串 # -> 符號後面是對函數返回值進行註解 # 這些註釋內容存儲在屬性 __annotations__中 print(foo.__annotations__) # {'step': 'int 間隔(大於0小於num)', 'num': <class 'int'>, 'return': <class 'int'>} # 這樣註釋後,在使用pycharm時會出現自動提示 |
python高級——目錄app