python-函數(shù)

函數(shù)

  • def add(x,y): 函數(shù)名add(標(biāo)識符)對應(yīng)一個內(nèi)存中的一個函數(shù)對象,因此也可以有多個標(biāo)識符同時指向這個對象,同樣可以調(diào)用。
  • 再次定義會創(chuàng)建一個新的function對象,不是對原來對象的修改;add(標(biāo)識符)指向這個新的對象,原來的函數(shù)對象引用計數(shù)減一。
  • 函數(shù)調(diào)用:add(2,3) 將(2,3)傳入add指向的函數(shù)對象中進(jìn)行計算
  • 函數(shù)是一個可調(diào)用對象;callable(add) ==> True
  • 函數(shù)傳參
    1、位置傳參;2、關(guān)鍵字傳參;3、可變位置傳參;4、keyworld-only;5、可變關(guān)鍵字傳參
  • 關(guān)鍵字參數(shù)必須在位置參數(shù)后面,每個參數(shù)只能接受一個值,否則多值錯誤;位置參數(shù)可以使用關(guān)鍵字傳參
def sum(*iterable):
    print(type(iterbale))  # iterbale ==> 元組,不傳入為空元組
    for i in iterable:
        pass
def sum1(iterable):
   print(type(iterbale))
       for i in iterable:
           pass
sum(x for i in range(10)))  # 傳入生成器
sum1(range(5)))  # 傳入一個對象
  • 可變位置參數(shù):收集所有位置參數(shù)作為一個元組。
  • 可變關(guān)鍵字參數(shù):收集所有關(guān)鍵字參數(shù)作為一個字典。
def fn(a, b=5, *args, **kwargs):
    pass
fn(5, a=2, c=3, b=4,z=5) 
##位置參數(shù)和關(guān)鍵字參數(shù)混用,關(guān)鍵字參數(shù)可以亂序,多余的kwargs收集為字典
  • keyword-only
    def fun(x=4, *args, y, **kwargs):  
    # y只能接受關(guān)鍵字參數(shù),keyword-only參數(shù)
    pass
    def func(*args, x=0, y):  # 正確,keyword-only 默認(rèn)值可以在前
    pass
    def func1(*,m): # m 必須為關(guān)鍵字傳參
    pass    
  • 元組,列表,字符串,迭代器,生成器,range對象 均可以解構(gòu)
  • 字典解構(gòu)傳參
def fun(a, b):
    pass
fun(**{"a":1,"b",2})               # ==> fun(a=1,b=2)
fun(*{"a":1,"b",2}.values())   # ==> fun(*(1,2))
  • 函數(shù)返回值:使用return 返回,函數(shù)執(zhí)行return后函數(shù)結(jié)束,并返回return 指定的內(nèi)容,未定義return默認(rèn)return None
  • 函數(shù)作用域:函數(shù)定義的變量只在該函數(shù)內(nèi)部,函數(shù)的局部作用域,也稱本地變量
  • 全局變量、全局作用域:全局可見,可以向內(nèi)部穿透,在函數(shù)內(nèi)部可見

    函數(shù)嵌套:

  • 執(zhí)行函數(shù)定義的時候不會執(zhí)行內(nèi)部的語句,內(nèi)部定義的函數(shù)無法執(zhí)行
    def func():
    x = 1
    def fn():
        x = x + 1  #  調(diào)用時將會報錯,未定義本地x的值之前,使用了本地的x
  • global:聲明全局變量,該作用域中的該變量將會在全局中尋找該變量。
    def func:
    global x # 聲明全局作用域,必須是全局作用域,上一層使用的nonlocal
    x = 1  # 在函數(shù)中可以定義全局變量,且執(zhí)行后外部可用
    x += 1 
    閉包
  • 閉包:函數(shù)嵌套使用時,內(nèi)層函數(shù)使用到了外層函數(shù)定義的局部變量,形成了閉包。
  • python 中實現(xiàn)閉包的方式:
    1.內(nèi)部可以外部引用類型的變量,并可對其進(jìn)行內(nèi)部修改
    def func():
    x = [1]
    def fn():
        x.append[4]
    return fn
    foo = func()
    foo()   #  每次輸出將會在上一次的結(jié)果上增加一個元素;x 的操作與外部形成了閉包

    2.也可以使用nonlocal實現(xiàn)閉包:內(nèi)部變量聲明使用外部定義的變量

    潼關(guān)網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián),潼關(guān)網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為潼關(guān)超過千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)營銷網(wǎng)站建設(shè)要多少錢,請找那個售后服務(wù)好的潼關(guān)做網(wǎng)站的公司定做!

def func():
    x = 1
    def fn():
        nonlocal x  #聲明該x 是外部變量 x  
        x = x + 1
    return fn
foo = func()
foo()  # 每次調(diào)用x 結(jié)果加1,foo函數(shù)未消亡,x 將不會被清除
  • 如果在內(nèi)部函數(shù)中定義一個變量,該變量名與外部變量名相同,那么這個變量只會使用內(nèi)部的定義的這個值,且需要滿足先賦值,后使用
    def func():
    x = 1
    def fn():
        y = x + 1  # 此處使用了x 變量,但是在下一行才定義x 所以錯誤
        x = y   #  此處定義了與外部變量同名變量,在本函數(shù)內(nèi)部所有范圍內(nèi)只能用該變量
        # 如果沒有第5行對x的重新定義,第4行中x將會使用外部的x變量
  • nonlocal:非該函數(shù)本地的變量,但是也不能是全局中的變量,在其他的任意一層定義即可使用該變量;函數(shù)多層嵌套時,使用nonlocal將會一層層向外部尋找該變量,直到最外層函數(shù)(非全局變量,不會匹配同名的global變量名)
    def fn():
    global c
    c = 0
    def fn1():
        c = 0
        def fn2():
            def fn3():
                nonlocal c  # 會使用5行的c值,與第3行的c不是同一個比變量
    #若沒有第5行的c定義,也無法匹配第3行的c變量。nonlocal無法匹配global變量  
  • global和nonlocal都只是申明本函數(shù)作用域內(nèi)該元素,并向上匹配尋找

    默認(rèn)值的作用域

  • 當(dāng)函數(shù)定義之后,會在內(nèi)存中生成一個函數(shù)對象 ,此時函數(shù)已經(jīng)定義了許多的方法和屬性(可以理解為函數(shù)的元數(shù)據(jù)),例如函數(shù)名字,默認(rèn)值等,函數(shù)參數(shù)的默認(rèn)值已被加載到函數(shù)的兩個屬性之中保存,分別為'. defaults','kwdefaults'中
    def fun(a, b=1, c={}, *d , m=1, **kw):
    a = 1
    x = 1
    return x
    dir(fun) # 查看該函數(shù)定義后的已經(jīng)存在屬性
    '''
    ['__annotations__', '__call__', '__class__', '__closure__',
    '__code__', '__defaults__', '__delattr__', '__dict__',
    '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
    '__get__', '__getattribute__', '__globals__', '__gt__', 
    '__hash__', '__init__', '__init_subclass__', '__kwdefaults__',
    '__le__', '__lt__', '__module__', '__name__', '__ne__', 
    '__new__', '__qualname__',  '__reduce__', '__reduce_ex__',
    '__repr__', '__setattr__', '__sizeof__', '__str__',
    '__subclasshook__']
    '''
    # 默認(rèn)值被保存到 __defaults__ 和 __kwdefaults__中,分別保存位置參數(shù)
    # (使用元組)和kw-only參數(shù)(使用字典)
    fun.__defaults__       # ==> ( 1, {} )   保存了b和c的缺省值
    fun.__kwdefaults__     # ==> {'m': 1}     保存了m 的默認(rèn)值
  • 注:當(dāng)默認(rèn)值為引用類型時,使用變量操作時可能會引起默認(rèn)值的改變(在使用默認(rèn)值時,進(jìn)行一些引起本對象的操作就會引起默認(rèn)值改變)
    如:list,bytearray,set,dict等可變類型對自身修改的操作,可變序列的 += 操作
    def fun(x = [], b=1):
    x.append(1)   # 此時 x 是默認(rèn)值列表中對象,直接操作默認(rèn)值參數(shù)的對象
    x += [1]         # += 執(zhí)行列表的extend,也是對x本對象的改變
    b = 2             #b原本指向默認(rèn)值列表中的1,現(xiàn)在指向新的對象2,原對象未改變
  • LEGB原則:尋找一個變量時候的先后順序
    python - 函數(shù)
  • 當(dāng)內(nèi)部定義一個與全局變量或者build-in中相同的變量名時,將會使得全局或者build-in中的函數(shù)無法在本程序內(nèi)使用,例如:
    print = 1   # 定義一個變量為print,此時print指向一個int對象,
    print(1)     #  此時將會報錯,默認(rèn)先使用本文件中的print,而不是build-in中

    匿名函數(shù)

    1. 匿名函數(shù)普通定義
    2. 定義后可以使用變量接收,此時等同于 def
    3. 創(chuàng)建對象后直接調(diào)用,在函數(shù)后部直接()進(jìn)行調(diào)用
      特點:簡潔,快速實現(xiàn)某種功能,一次性創(chuàng)建使用,節(jié)省內(nèi)存。
      lambda x : x + 1    #  返回值===> 對象,":"后不能出現(xiàn)賦值表達(dá)式
      foo = lambda x : x + 1  # ===> 返回的對象使用一個變量接收,foo可調(diào)用
      (lambda x : x+1)(1)  # ==> 直接在創(chuàng)建后調(diào)用,()+ 傳入?yún)?shù)調(diào)用
  • 使用場景
    構(gòu)造一個類型,完成某種功能
    # 返回一個和str功能相同的函數(shù)對象,效果相同
    sorted([1,2,3,"a"], key = str)
    sorted([1,2,4,"a"], key = lambda x :str(x))
    # 可以定制一些自己的比較方式,例如:
    sorted([1,2,4,"a"], key = lambda x :hash(x)) # 使用元素哈希值排序
    sorted([1,2,4,"a"], key = lambda x :func(x)) # func為自己定義的函數(shù),實現(xiàn)自定義
  • 構(gòu)造某些類型,使用其返回值
d = defalutdict(lambda :0)
for k in "abc":
    d[k] += 1   # 第一次將會調(diào)用lambda并返回初始值0值,完成累加

d = defalutdict(lambda :[])    # 構(gòu)造列表 == list
for k in "abc":
    d[k].append(1)
  • 嵌套使用,可用于閉包
    def fun():
    x =  [ ]
    return lambda  a : x.append(a)   # 匿名函數(shù)使用外層函數(shù)x,形成閉包

    遞歸函數(shù)

  • 函數(shù)調(diào)用過程:函數(shù)定義后,會在內(nèi)存中生成函數(shù)對象,在調(diào)用函數(shù)時,函數(shù)將會在main函數(shù)之上壓棧,對應(yīng)的參數(shù)分別進(jìn)行壓棧,函數(shù)全部執(zhí)行結(jié)束,函數(shù)對象進(jìn)行彈棧,繼續(xù)執(zhí)行main函數(shù);如果函數(shù)未進(jìn)行彈出棧時調(diào)用新的函數(shù),函數(shù)將會繼續(xù)壓棧,直到棧上層函數(shù)執(zhí)行完成彈出后下層函數(shù)才會依次彈出;先進(jìn)棧函數(shù)后出棧,后進(jìn)棧函數(shù)一定會先彈出才能彈出下層函數(shù)
  • 遞歸函數(shù):在自己函數(shù)內(nèi)部反復(fù)調(diào)用自己,形成一個循環(huán)的調(diào)用。
  • 間接遞歸:A調(diào)用B函數(shù),B調(diào)用C,C調(diào)用A形成間接的遞歸調(diào)用
  • 注:遞歸必須有邊界條件,達(dá)到某個條件將對停止自身調(diào)用,并進(jìn)行一層層的return 返回,這是一個“逆向”的操作,先執(zhí)行內(nèi)部函數(shù),在執(zhí)行外層函數(shù) ;
    內(nèi)層函數(shù)的 return 值將會成為外一層函數(shù)調(diào)用結(jié)果,注意 return 值的控制。
  • 遞歸思路:找出遞推公式,即:F( n) = f ( n - 1) 的關(guān)系,有了該關(guān)系,基本可以寫成以下形式
  • def func(n):
    if n == ?                   # 退出條件,可能不止一個
        return ?               # 一個確定的值,不可以再調(diào)用自身
    return func( n - 1 )  #  根據(jù)實際遞推公式變化    
  • 遞歸分析: 分析返回結(jié)果 習(xí)慣從最里層分析。
  • 遞歸最大深度:無限遞歸將會消耗所有的棧資源,所以python中對遞歸層數(shù)進(jìn)行了限制,查看方法:
    import sys 
    print(sys.getrecursionlimit())  # ==> 最大遞歸數(shù)
  • 遞歸會使用大量函數(shù)的壓棧,開辟和清理新的??臻g需要時間和資源,效率較低;一般不使用

生成器函數(shù)

yield關(guān)鍵字
  • yield只能在函數(shù)中使用,當(dāng)函數(shù)中有yield關(guān)鍵字,該函數(shù)執(zhí)行時將會返回一個 生成器對象,每次使用 next驅(qū)動,遇到y(tǒng)ield語句暫停執(zhí)行,等待下一次next,但當(dāng)執(zhí)行到return 語句時,將結(jié)束生成器運行。
    def func():
    for i in range(3):
        yield i                   #  執(zhí)行到y(tǒng)ield,返回一次結(jié)果,并暫停函數(shù)執(zhí)行 
    f = func()                     # 調(diào)用函數(shù)將不會執(zhí)行,而是返回一個生成器對象
    next(f)                        # 使用next(),返回每次yield值 
    每次調(diào)用函數(shù)func 將會返回一個新的生成器,不能直接對func()進(jìn)行操作,否則每次生成新的對象。
  • 每次調(diào)用函數(shù)func 將會返回一個新的生成器,不能直接對func()進(jìn)行操作,否則每次生成新的對象。
  • 函數(shù)中如果有return語句,執(zhí)行return語句將會結(jié)束函數(shù),但是無法拿到return返回值。
  • 使用next函數(shù)執(zhí)行到最后將會報錯,StopIteration
    .send()方法
  • send()是生成器對象的一個方法,會推動生成器函數(shù)執(zhí)行,直到遇到 yield 語句,并接受返回的yield 的值,同時,send會將實參傳入生成器函數(shù)內(nèi)部yield語句,作為yield函數(shù)體內(nèi)部執(zhí)行后的返回值,從而實現(xiàn)生產(chǎn)器函數(shù)內(nèi)部的一種“交互”
    def foo():
    i = 0
    while True:
        i += 1
        res = yield i           #yield 的默認(rèn)返回值None,外部使用send后將返回send值
        print(res)
    g = foo()
    g.send("abc")                # 執(zhí)行next(g),并將"abc"作為生成器g內(nèi)部yield的返回值 

    使用案例:重置計數(shù)器,send任意值重置計數(shù)

    def foo():
    i = 0
    while True:
        i += 1
        res = yield i                # 第一次執(zhí)行會返回i, 然后暫停函數(shù)的執(zhí)行
        if res is not None:      # 當(dāng)收到send值,重置計數(shù)器i
            i = 0
        print(res)                    # 下一次next,才會使用res 即"abc"
    g = foo()                             # 生成器對象
    g.send("abc")
    yield from
    # 每一次執(zhí)行返回可迭代對象中的一個值
    def foo():
    yield from [1,2,3]                 # 接iterable

    高階函數(shù)

    定義及實現(xiàn)

  • 高階函數(shù):參數(shù)中至少有一個函數(shù),或者返回值是一個函數(shù)對象的函數(shù)
    下面 key 參數(shù)的實現(xiàn)為高階函數(shù)的實現(xiàn)原理,利用高階函數(shù),自行實現(xiàn)sorted排序函數(shù)
    a = [8, 7,6, 47, 464, 4, 32,3,2]
    def sort(nums, *, key=None, reverse=False):
    res = []
    for x in nums:
        for i, v in enumerate(res):                          #第一次不會for,append第一個元素
            cx = key(x) if key else x                        #key實現(xiàn)
            cv = key(v) if key else v                        #只用于比較,插入時使用原值 
            cmp = cx > cv if reverse else cx < cv    # reverse實現(xiàn)
            if cmp: 
                res.insert(i,x)                                     # 找到插入位置i , 插入 x 
                break
        else:
            res.append(x)
    print(res)
    sort(a, reverse=1, key=str)

    常用高階函數(shù)

    sorted()
    排序函數(shù):返回排序好的原列表

    # sorted(iterbale, *, key=None, reverse=False)
    # 結(jié)合 lambda 實現(xiàn)特定功能
    # 使用 lambda 按照其lambda返回值的數(shù)值大小依次進(jìn)行排序
    sorted(a, key=lambda x: abs(x-10) )     # 以x-10的絕對值大小排序
    sorted(a, key=lambda x: 1)                   # 原來的序列

    filter()

  • 將可迭代對象中的每個元素放入function中,將function 返回值為等效false 的元素進(jìn)行過濾
  • function接受一個參數(shù),且返回值應(yīng)當(dāng)是bool類型,或其返回值等效布爾值
  • function參數(shù)如果是None,可迭代對象的每一個元素自身等效布爾值
    # filter(function, iterable)  ==> 迭代器,惰性對象
    list(filter(int, ["0", "12"]))             # ==> ["12"]  #int("0")后等效false
    list(filter(lambda x: int(x), ["0", "12"]))                 # 同上功能
    filter(None, [None, 0, "False", False, [],"",(), {}])  # ['False']

    map()

    # map(self, /, *args, **kwargs)
    # map(func, *iterables) --> map object  # 返回map對象,惰性  
    map(str, range(5))                         # [ '0, '1', '2', '3', '4']
    map(lambda x: str(x), range(5))       # 同上
    map(lambda x,y: (x,y), "abcde", range(10))      # 類似zip,返回組合后的元組

分享標(biāo)題:python-函數(shù)
URL鏈接:http://muchs.cn/article4/jpdgie.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營銷、網(wǎng)站內(nèi)鏈、網(wǎng)站策劃、小程序開發(fā)、做網(wǎng)站、App設(shè)計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名