python高級(五)—— python函數(一等對象)

本文主要內容

一等對象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__']
    '''
    
    # 下表對一些屬性作了說明
名稱 類型 說明
__annotations__ dict 參數和返回值的註解
__call__ method-wrapper 實現()運算符
__closure__ tuple 函數閉包
__code__ code 編譯成字節碼的函數元數據和函數定義體
__defaults__ tuple 形式參數的默認值
__get__ method-wrapper 實現只讀描述符協議
__globals__ dict 函數所在模塊中的全局變量
__kwdefaults__ dict 僅限關鍵字形式參數的默認值
__name__ str 函數名稱
__qualname__ str 函數的限定名稱

 

函數註釋

'''
    函數註解很簡單,用下面例子簡單講解便可明瞭
'''


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高級系列文章目錄

python高級——目錄app

相關文章
相關標籤/搜索