久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

python到底還有哪些函數(shù)我們還沒(méi)見(jiàn)過(guò)?原來(lái)有這么多實(shí)用的函數(shù)

 正合叔 2020-12-14

本文將將主要介紹如下內(nèi)容

python到底還有哪些函數(shù)我們還沒(méi)見(jiàn)過(guò),?原來(lái)有這么多實(shí)用的函數(shù)

函數(shù)介紹

1.1 函數(shù)的定義

所謂的函數(shù),,其實(shí)就是具有特定功能的一段代碼塊,都可以獨(dú)立的運(yùn)行 ,。

函數(shù)有5部分組成,,分別是定義函數(shù)的關(guān)鍵字,函數(shù)的名字,,圓括號(hào)(存放函數(shù)的參數(shù)),,函數(shù)功能的實(shí)現(xiàn),函數(shù)的返回語(yǔ)句,。

  • 函數(shù)的關(guān)鍵字,,定義函數(shù)要使用關(guān)鍵字def開(kāi)頭,后面跟著函數(shù)的名字 。兩者中間相隔一個(gè)空格,。
  • 函數(shù)的名字,,每個(gè)函數(shù)都要有一個(gè)名字即函數(shù)標(biāo)識(shí)符,函數(shù)名字是由開(kāi)發(fā)人員起的,,起的名字最好有一定業(yè)務(wù)語(yǔ)義,比如此功能是一個(gè)加法的操作,,那么就可以起add.
  • 圓括號(hào),,圓括號(hào)內(nèi)可以定義參數(shù),參數(shù)可以是一個(gè),,也可以是多個(gè),,也可以沒(méi)有參數(shù) 。圓括號(hào)后必須要有個(gè)冒號(hào)并且加縮進(jìn),,
  • 函數(shù)功能實(shí)現(xiàn)代碼,,冒號(hào)+縮進(jìn)的后面就可以編寫(xiě)函數(shù)的功能代碼塊了,但這部分一般都是放在函數(shù)的下一行 ,。
  • 函數(shù)的返回語(yǔ)句,,函數(shù)使用return代表函數(shù)已經(jīng)結(jié)束,不帶表達(dá)式return代表返回None ,。

函數(shù)的語(yǔ)法格式:

def 函數(shù)名(參數(shù)列表):    函數(shù)體    return

示例:

#不帶參數(shù)的函數(shù)def hello_world():    print('hello world')
#帶一個(gè)參數(shù)def show(msg) print(msg)
#帶多個(gè)參數(shù)def add(x,y):    z = x + y    return z

1.2函數(shù)的調(diào)用

調(diào)用函數(shù),,其實(shí)就是使用函數(shù)。調(diào)用函數(shù)時(shí)直接使用函數(shù)名即可,。

調(diào)用語(yǔ)法:

函數(shù)名(參數(shù)列表)

調(diào)用以上定義的函數(shù)

#1.調(diào)用hello_world函數(shù)hello_world()#2.調(diào)用show函數(shù)show('我是一個(gè)函數(shù)')      #輸出:我是一個(gè)函數(shù)#3.調(diào)用add函數(shù)print(add(3,4))         #輸出:7

1.3函數(shù)的返回

函數(shù)的返回用于退出該函數(shù),,函數(shù)返回使用return進(jìn)行表示,return后面可以根具體值,,也可以不跟,。如果不跟任何值代表返回None。

一般return后的值有以下幾種情況:

  • return None,,如果是None,,可以忽略不寫(xiě) 。
  • return value,,value可以是代碼塊中計(jì)算出來(lái)的值,,也可以是一個(gè)表達(dá)式 。
  • return val1,...,valn,。return也可以返回多個(gè)值,,注意:返回多個(gè)值時(shí)接收需用對(duì)應(yīng)的多個(gè)變量。

示例

def show(msg):    print(msg)    return None #這樣代碼可以忽略,。def add(x,y):    z = x +y    return z #返回某個(gè)值def add(x,y):    return x + y #直接返回參與運(yùn)算后的結(jié)果def calc(x,y):    add = x+y    sub = x-y    return add,sub #返回了兩個(gè)值

1.4 小結(jié)

最后,,我們將上面講的內(nèi)容通過(guò)一張思維導(dǎo)圖來(lái)總結(jié),具體如下

python到底還有哪些函數(shù)我們還沒(méi)見(jiàn)過(guò)?原來(lái)有這么多實(shí)用的函數(shù)

函數(shù)的參數(shù)

在調(diào)用函數(shù)時(shí),,經(jīng)常會(huì)用到形式參數(shù)(簡(jiǎn)稱(chēng)“形參”)和實(shí)際參數(shù)(簡(jiǎn)稱(chēng)“實(shí)參”),二者的主要區(qū)別是:

  • 形式參數(shù),,是在括號(hào)內(nèi)的參數(shù)就叫形式參數(shù),例如上面add函數(shù):
def add(x,y):           #這里的x,y就是形式參數(shù)    z = x + y    return z
  • 實(shí)際參數(shù),,調(diào)用函數(shù)時(shí),,實(shí)際傳入到函數(shù)內(nèi)的值 。
print(add(3,4)) #調(diào)用add函數(shù)時(shí),,實(shí)際傳入的3和4就是實(shí)際參數(shù) ,。

需要注意的是,一個(gè)函數(shù)實(shí)際上可以接受任何類(lèi)型的值,,比如字符串,,整數(shù),浮點(diǎn)數(shù),,列表,,元組,字典等,。

當(dāng)函數(shù)的形式參數(shù)中要傳遞實(shí)際的值時(shí),,也會(huì)分兩種情況,不可變對(duì)象值(值傳遞)傳遞和可變對(duì)象值傳遞(引用傳遞),。

函數(shù)中的不可變對(duì)象值傳遞,,示例:

x = 10def sum(a):    a += 2    return aprint('調(diào)用函數(shù)后返回的值:',sum(x))print('x的值:',x)

運(yùn)行后可以看出,無(wú)論函數(shù)中如何作用x的值,,實(shí)際的x值是不會(huì)發(fā)生變化的 ,,傳入sum函數(shù)里的值其實(shí)就是x=10的一份副本 。

python到底還有哪些函數(shù)我們還沒(méi)見(jiàn)過(guò),?原來(lái)有這么多實(shí)用的函數(shù)

函數(shù)中的可變對(duì)象傳遞,,示例

my_lst = ['java', 'c++', 'python','go']def update_lst(lst):    lst.insert(1,'ruby')    return lstprint('調(diào)用函數(shù)后返回的值:',update_lst(my_lst))print('my_lst的值:',my_lst)

運(yùn)行結(jié)果:

python到底還有哪些函數(shù)我們還沒(méi)見(jiàn)過(guò)?原來(lái)有這么多實(shí)用的函數(shù)

以上結(jié)果可以看出,,通過(guò)函數(shù)作用于my_list列表后,,列表內(nèi)的值也發(fā)生改變了,他們兩同時(shí)指向了一個(gè)列表 ,。

最后,,用個(gè)形象的例子總結(jié)一下,不可變對(duì)象就像是一個(gè)pdf文件,,文件內(nèi)容本身不能改變,,但是可以拷貝,所以在函數(shù)中使用不可變對(duì)象都是使用的是拷貝后的副本,。而可變對(duì)象就像是execl,。execl中的內(nèi)容是可變化的 。但是操作的都是源文件,函數(shù)中操作的可變對(duì)象也是對(duì)源文件里的內(nèi)容進(jìn)行操作 ,。

從參數(shù)的類(lèi)型劃分,,可以將參數(shù)劃分為:位置參數(shù),默認(rèn)參數(shù),,關(guān)鍵字參數(shù),,可變參數(shù)。

2.1 位置參數(shù):

所謂的位置參數(shù),,主要是指輸入函數(shù)內(nèi)的參數(shù)數(shù)量和位置要和定義的形參中的一致,。傳多或傳少都會(huì)報(bào)錯(cuò)。

#實(shí)例:def add(x,y):           #定義了兩個(gè)形參,,調(diào)用該方法時(shí)必須傳入兩個(gè)參數(shù)值,傳多或傳少都會(huì)報(bào)錯(cuò)    z = x + y    return z#輸出print(1,2)      #位置參數(shù)傳入正確print('hello','world')  #位置參數(shù)傳入正確print(3)        #不正確,,報(bào)TypeError異常print(1,2,3)    #不正確,,報(bào)TypeError異常

2.2 默認(rèn)參數(shù)

如果函數(shù)的某個(gè)參數(shù)經(jīng)常會(huì)使用到一個(gè)值,那我們就可以給這個(gè)參數(shù)設(shè)置一個(gè)默認(rèn)值 ,,當(dāng)調(diào)用該函數(shù)時(shí),,該參數(shù)若不傳入值,就會(huì)使用到默認(rèn)值,。設(shè)置的默認(rèn)參數(shù)需放在關(guān)鍵字參數(shù)后 ,。

示例:

#默認(rèn)參數(shù)實(shí)例def show_lgg(msg,lgg='python'):    info = ('{}{}'.format(msg,lgg))    return infoprint(show_lgg('使用默認(rèn)的開(kāi)發(fā)語(yǔ)言:'))print(show_lgg('使用默認(rèn)的開(kāi)發(fā)語(yǔ)言:','java'))#輸出使用默認(rèn)的開(kāi)發(fā)語(yǔ)言:python使用默認(rèn)的開(kāi)發(fā)語(yǔ)言:java

從以上結(jié)果可以看出,函數(shù)show_lgg中的lgg設(shè)置了默認(rèn)值python,,當(dāng)該參數(shù)沒(méi)有傳值時(shí),,使用的是默認(rèn)的值。若該參數(shù)傳入值后,,使用的就是傳入的值 ,。

那這個(gè)默認(rèn)參數(shù)的用處就是,當(dāng)函數(shù)的參數(shù)值頻繁的使用某一個(gè)值或者優(yōu)先被使用該值時(shí),,都可以將其設(shè)置為默認(rèn)值 ,。比如我們經(jīng)常使用的瀏覽器,那么多的瀏覽器中,,我們最常用的Chrome,,那么就可以將Chrome設(shè)置為默認(rèn)值。不傳入該參數(shù)時(shí)默認(rèn)就會(huì)使用Chrome ,。

使用默認(rèn)參數(shù)時(shí)要注意,,位置參數(shù)需放在默認(rèn)參數(shù)前面,否則python會(huì)報(bào)錯(cuò),。使用它可以簡(jiǎn)化我們的調(diào)用,,增加靈活度。

2.3 關(guān)鍵字參數(shù)

關(guān)鍵字參數(shù)是指?jìng)鬟f給參數(shù)要以key=value形式,key代表函數(shù)中的形參名稱(chēng),,value就是傳遞給函數(shù)的實(shí)際的值,。

使用關(guān)鍵字參數(shù)后,參數(shù)的位置就可以進(jìn)行調(diào)換了 ,。

#關(guān)鍵字參數(shù)實(shí)例def student_lesson(grade,subject):    z = '{}年級(jí)上{}課'.format(grade,subject)    return zprint(student_lesson(3,'英語(yǔ)'))           #位置參數(shù)print(student_lesson(grade=4,subject='數(shù)學(xué)'))     #關(guān)鍵字參數(shù)print(student_lesson(subject='語(yǔ)文',grade=5))     #關(guān)鍵字參數(shù)可以調(diào)換位置print(student_lesson(6,subject='體育'))           #關(guān)鍵字參數(shù)和位置參數(shù)混合使用,。#輸出3年級(jí)上英語(yǔ)課4年級(jí)上數(shù)學(xué)課5年級(jí)上語(yǔ)文課6年級(jí)上體育課

以上方式都可以正常正常調(diào)用,但是需要注意的是,,當(dāng)關(guān)鍵字參數(shù)和位置參數(shù)混合使用時(shí),,位置參數(shù)必須在前,關(guān)鍵字參數(shù)在后,,否則會(huì)報(bào)錯(cuò),。

2.4 可變參數(shù)

這里的可變化參數(shù)指的參數(shù)的數(shù)量可以發(fā)生變化,比如我可以傳遞3個(gè)參數(shù),,也可以傳遞6個(gè),,甚至更多 ??勺兓瘏?shù)有兩種類(lèi)型,,分別是用來(lái)接收元組或列表形式的可變參數(shù);另外一種是用來(lái)接收字典形式的可變參數(shù) ,。

#列表形式的語(yǔ)法格式:def fun_name(a,b,*args):    pass?#代碼實(shí)例def show_info(*args):    print(args)show_info() #可變參數(shù)也可以不傳入任何參數(shù)show_info('python') #傳入一個(gè)參數(shù)show_info('python','java') #傳入多個(gè)參數(shù)show_info(*['python','java']) #傳入列表,,注意,列表前需要加*show_info(*('python','java')) #傳入元組,,元組前也需要加*#輸出:()('python',)('python', 'java')('python', 'java')('python', 'java')

在可變參數(shù)的參數(shù)名前需加*代,,這樣就代表該參數(shù)為可變參數(shù)了。同時(shí)也傳入的時(shí)候可以是一個(gè)值,,多個(gè)值,,列表或元組 。

還有一種可變參數(shù)就是接收字典中的元素 ,。在函數(shù)中是以雙星**表示,。此函數(shù)同樣能接收多個(gè)位置參數(shù),但是傳入的形式需要以關(guān)鍵字形式傳遞 ,。

#字典形式的可變參數(shù)語(yǔ)法格式def fun_name(a,b,**kw):     pass    #代碼實(shí)例def show_info(**kwargs):    print(kwargs)show_info()                                 #可變參數(shù)也可以不傳入任何參數(shù)show_info(key1='python')                            #傳入一個(gè)參數(shù)show_info(key1='python',key2='java')                    #傳入多個(gè)參數(shù)show_info(**{'key1':'python','key2':'java'})                #傳入列表,,注意,列表前需要加*#輸出:{}{'key1': 'python'}{'key1': 'python', 'key2': 'java'}{'key1': 'python', 'key2': 'java'}

也可以將可變參數(shù)列表和字典形式結(jié)合起來(lái)使用 ,。

def fun_name(*args,**kwargs): #此函數(shù)可以接收任何長(zhǎng)度,,任何位置,任何關(guān)鍵字的參數(shù) ,。    pass

針對(duì)以上四種參數(shù),,進(jìn)行總體說(shuō)明:

  • 位置參數(shù),,參數(shù)的順序和個(gè)數(shù)固定,調(diào)用函數(shù)時(shí)也必須按照該順序和個(gè)數(shù)進(jìn)行傳遞 ,。但如果參數(shù)個(gè)數(shù)固定了,,就不容易擴(kuò)展了 。所以,,可以使用可變參數(shù)傳入不同數(shù)量的參數(shù) ,。
  • 關(guān)鍵字參數(shù),使用形參名稱(chēng)=輸入的值來(lái)進(jìn)行表示,,如果使用關(guān)鍵字參數(shù),,就可以調(diào)換參數(shù)的位置 ,可變參數(shù)的字典形式其實(shí)就是關(guān)鍵字參數(shù)的擴(kuò)展,,可以支持不同長(zhǎng)度的關(guān)鍵字參數(shù),。
  • 默認(rèn)參數(shù),是針對(duì)位置參數(shù)的,,相當(dāng)于給某一個(gè)或幾個(gè)位置參數(shù)設(shè)置默認(rèn)值,。
  • 可變化參數(shù),可以擴(kuò)展位置參數(shù)的數(shù)量,,支持列表形式和字典形式的位置參數(shù) 。

2.5 小結(jié)

最后,,我們將上面講的內(nèi)容通過(guò)一張思維導(dǎo)圖來(lái)總結(jié),,具體如下

python到底還有哪些函數(shù)我們還沒(méi)見(jiàn)過(guò)?原來(lái)有這么多實(shí)用的函數(shù)

高級(jí)函數(shù)

3.1 匿名函數(shù)

使用關(guān)鍵字lambda的表達(dá)式,,又稱(chēng)為匿名函數(shù),。若函數(shù)可以用一行進(jìn)行實(shí)現(xiàn)的話(huà),那么該函數(shù)就可以使用匿名函數(shù)來(lái)代替,。

#格式:    lambda x,y,...,n:表達(dá)式#說(shuō)明:x,y,...,n.相當(dāng)于普通函數(shù)的位置函數(shù),,可以是一個(gè),也可以是多個(gè) ,。#實(shí)例:求兩個(gè)數(shù)的和    #實(shí)現(xiàn)1:普通實(shí)現(xiàn)    def add(a,b):        return a + b        z1 = add(3,4)    print(z1)           #輸出:7        #實(shí)現(xiàn)2:通過(guò)匿名函數(shù)    z2 = lambda x,y:x+y    print(z2)           #<function <lambda> at 0x0326C618>    print(z2(4,5))      #輸出:9

匿名函數(shù)除了可以賦值給變量外,,還可以通過(guò)函數(shù)的參數(shù)來(lái)傳遞參數(shù)。

#實(shí)現(xiàn):將函數(shù)的參數(shù)a,b傳遞給匿名函數(shù)def add(a,b):    z = lambda :a+b    return z

3.2 高階函數(shù)-map,reduce,filter,sorted

map函數(shù)

map()是python的內(nèi)置函數(shù),。map()函數(shù)接收兩個(gè)或多個(gè)參數(shù),,第一個(gè)參數(shù)接收的是函數(shù),后面的參數(shù)是序列,。

#語(yǔ)法:    map(函數(shù),序列)        #實(shí)例:將列表中的每一對(duì)元素相加lst = [(1,2),(3,4),(4,5)]total = map(sum,lst)print(list(total))#輸出:[3, 7, 9]#說(shuō)明:    以上代碼相當(dāng)于把(1,2),(3,4),(4,5)這三組中的每?jī)蓚€(gè)元素傳遞給sum,,然后由sum來(lái)進(jìn)行運(yùn)算 。

map后面的序列也可以是多個(gè)

#語(yǔ)法: map(函數(shù),序列1,序列2,...)    #實(shí)例num = map(lambda x,y:x+y,[1,2,3,4,5],[6,7,8,9,10])print(list(num))#輸出:[7, 9, 11, 13, 15]#說(shuō)明: map的第二個(gè),,第三個(gè)參數(shù)都是列表,,結(jié)果就是將這兩個(gè)列表每一個(gè)位置的數(shù)進(jìn)行相加

reduce函數(shù)

接收兩個(gè)參數(shù),,第一個(gè)是函數(shù),第二個(gè)是序列 ,。reduce()函數(shù)會(huì)把序列中的每一個(gè)元素累積進(jìn)行計(jì)算,,如何計(jì)算由前面的函數(shù)來(lái)定。

#語(yǔ)法:    reduce(函數(shù),序列)    #實(shí)例:把列表中的數(shù)進(jìn)行相加from functools import reducedef add(x,y):    return x + ysum = reduce(add,[1,2,3,4,5])print(sum)#輸出:15#說(shuō)明:相當(dāng)于是把整個(gè)列表的數(shù)進(jìn)行了一次循環(huán)的相加操作

filter函數(shù)

也是接收兩個(gè)參數(shù),,第一個(gè)是函數(shù),,第二個(gè)是序列,filter()函數(shù)會(huì)把傳入的函數(shù)依次作用于每個(gè)元素,,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素,。

#語(yǔ)法: filter(函數(shù),序列)    #實(shí)例:查詢(xún)字典中成績(jī)分大于350分的元素dt = {'grade_one': 237, 'grade_two': 532, 'grade_three': 356}dt1 = dict(filter(lambda x:x[1] > 350,dt.items()))print('查詢(xún)年級(jí)分?jǐn)?shù)大于350分的班級(jí):{}'.format(dt1))#輸出:查詢(xún)年級(jí)分?jǐn)?shù)大于350分的班級(jí):{'grade_two': 532, 'grade_three': 356}

sorted函數(shù)

sorted函數(shù)對(duì)所有可迭代的對(duì)象進(jìn)行排序

#語(yǔ)法    sorted(iterable, cmp=None, key=None, reverse=False)     ==等價(jià)于下面的    sorted(可迭代對(duì)象,比較函數(shù),用來(lái)比較的元素,排序規(guī)則)    #實(shí)例:    study = [('ruby', '3本', 150), ('python', '21本', 122), ('java', '18本', 210)]    print('按第三個(gè)元素(價(jià)格)排序:{}'.format(sorted(study, key=lambda s: s[2])))    print('按第二個(gè)元素(書(shū)籍)降序排序:{}'.format(sorted(study, key=lambda s:s[2],reverse=True)))    #輸出:    按第三個(gè)元素(價(jià)格)排序:[('python', '21本', 122), ('ruby', '3本', 150), ('java', '18本', 210)]    按第二個(gè)元素(書(shū)籍)降序排序:[('java', '18本', 210), ('ruby', '3本', 150), ('python', '21本', 122)]     

3.3 偏函數(shù)

偏函數(shù)其實(shí)就是functools包中的partial函數(shù),。

在前面我們講到函數(shù)的默認(rèn)值可以減少傳遞參數(shù)的數(shù)量,,但是一旦定義了函數(shù)的默認(rèn)值,如果修改的話(huà),,就得修改這個(gè)函數(shù),,很多情況我們底層的一些函數(shù)都是不建議修改的,這個(gè)時(shí)候可以使用偏函數(shù)來(lái)設(shè)置默認(rèn)值,,而且不同的類(lèi)型可以設(shè)置不同的默認(rèn)值 ,。

#簡(jiǎn)化版計(jì)算器def calc(x,y,op='+'):    if op == '+':        return x + y    if op == '-':        return x - y    if op == '*':        return x * y    if op == '/':        return x / y    return x + y#需求:這時(shí)我們又需要進(jìn)行大量的乘法操作,怎么辦呢,? 如下面的操作calc(2,3,'*')calc(2,4,'*')calc(2,5,'*')...calc(2,n,'*')#注意:這個(gè)時(shí)候不建議修改原函數(shù),,因?yàn)樵瘮?shù)也是綜合考慮使用+最多的。不能這時(shí)用*就修改原函數(shù)為* ,。#問(wèn)題:每次傳入的第三個(gè)值都是一個(gè)值,,比較麻煩。能否把它作為默認(rèn)參數(shù)傳進(jìn)來(lái),,#解決方案:使用偏函數(shù)from functools import partialmult=partial(calc,op='*') #把乘法固定print(mult(2,4)) #輸出:8print(mult(6,4)) #輸出:24#說(shuō)明,,使用偏函數(shù)后,參數(shù)op的默認(rèn)值已經(jīng)給定,,所以后面不需要再傳遞該參數(shù) ,。

3.4 遞歸

遞歸就是函數(shù)內(nèi)部又調(diào)用了自己的函數(shù)就被稱(chēng)為遞歸 。

#語(yǔ)法格式def funA(    ...    funA()    ...)#實(shí)例1:求:1,!+2,!+3!+4,!+5,!+...+n!def factorial(n):    ''' n表示階乘數(shù)的最大值 '''    if n==1:        return n # 階乘為1的時(shí)候,結(jié)果為1,返回結(jié)果并退出    n = n*factorial(n-1) # n! = n*(n-1)!    return n  res = factorial(5) print(res) #輸出:120#===============================#實(shí)例21,,1,,2,,35,,8,,1321,,34,,55,試判斷數(shù)列第23個(gè)數(shù)是哪個(gè),?def fab(n):    ''' n為斐波那契數(shù)列 '''    if n <= 2:        ''' 數(shù)列前兩個(gè)數(shù)都是1 '''        val = 1        return val     val = fab(n-1)+fab(n-2) # 由數(shù)據(jù)的規(guī)律可知,,第三個(gè)數(shù)的結(jié)果都是前兩個(gè)數(shù)之和,所以進(jìn)行遞歸疊加    return valprint(fab(23))#輸出:28657

3.5 閉包和裝飾器

閉包

閉包又稱(chēng)為閉合函數(shù),。簡(jiǎn)單來(lái)說(shuō),,閉包的概念就是在函數(shù)內(nèi)再定義一個(gè)函數(shù),這個(gè)內(nèi)部函數(shù)使用了外部函數(shù)的臨時(shí)變量,,且外部函數(shù)的返回值是內(nèi)部函數(shù)的引用時(shí),,我們稱(chēng)之為閉包。

語(yǔ)法: def outer_func(): #外部函數(shù)        temp = null #外部函數(shù)的臨時(shí)變量        def inner_func():            函數(shù)體        return inner_func #將內(nèi)部函數(shù)作為返回值返回    #實(shí)例import operatordef operating(op): #外部函數(shù)定義具體的操作符    def calc(a,b): #內(nèi)部函數(shù)定義計(jì)算的兩個(gè)變量        oprt = {            '+': operator.add(a,b),            '-': operator.sub(a,b),            '*': operator.mul(a,b),            '/': operator.truediv(a,b)       }        return oprt.get(op)    return calc #把內(nèi)函數(shù)的引用當(dāng)做外函數(shù)的變量值返回add = operating('+')print(add(3,4)) #輸出:7

那么,,閉包最主要的用途就是裝飾器 ,。

裝飾器

裝飾器的本質(zhì)其實(shí)就是一個(gè)閉包函數(shù),以下就是一個(gè)最為普通的裝飾器,,

def info(func):    def wrapper():        print('[INFO]: 調(diào)用 {}()'.format(func.__name__))        return func()    return wrapperdef say():    print('hello!')say_hello = info(say)  # 添加功能并保持原函數(shù)名不變

通過(guò)和閉包進(jìn)行相比較,,兩者的寫(xiě)法都是一樣的,其實(shí)裝飾器就是一個(gè)閉包函數(shù) ,。那么除了以上調(diào)用方法外,python在后續(xù)的版本又引入了@語(yǔ)法糖,,同樣是上面的代碼,,可以使用如下方式調(diào)用 。

def info(func):    def wrapper():        print('[INFO]: 調(diào)用 {}()'.format(func.__name__))        return func()    return wrapper@infodef say():    print('hello!')    say()#輸出:[INFO]: 調(diào)用 say()hello!

這樣的話(huà),,就通過(guò)@ 標(biāo)識(shí)符將裝飾器應(yīng)用到函數(shù)上了 ,。其實(shí)通過(guò)以上的調(diào)用,實(shí)際上是執(zhí)行了如下2步操作:

  1. 將say傳給info()函數(shù) ,。
  2. 將info函數(shù)執(zhí)行完成的返回值反饋say

以上是一個(gè)最簡(jiǎn)單的裝飾器,,但有一個(gè)問(wèn)題,如果被裝飾的函數(shù)需要傳入?yún)?shù),,那么這個(gè)裝飾器就不能用了 ,,因?yàn)榉祷氐暮瘮?shù)并不能接受參數(shù) 。

帶參數(shù)的函數(shù)裝飾器

通過(guò)制定裝飾器函數(shù)wrapper接受和原函數(shù)一樣的參數(shù),,就可以參數(shù)了 ,。

def info(func):    def wrapper(arc):  #        print('[INFO]: 調(diào)用 {}()'.format(func.__name__))        return func(arc)    return wrapper  # 返回包裝過(guò)函數(shù)@infodef say(arc):    print('hello {}.'.format(arc))    say('裝飾器函數(shù)')    #輸出[INFO]: 調(diào)用 say()hello 裝飾器函數(shù).

以上還是只能接受一個(gè)參數(shù),,但實(shí)際情況下,同一個(gè)裝飾器可用于多個(gè)不同的函數(shù),,每個(gè)函數(shù)所帶的參數(shù)都各不相同,,怎么解決呢 ?

這時(shí)我們就可以用到可變參數(shù)*args和**kwargs了,。通過(guò)這兩個(gè)參數(shù),,裝飾器就可以用于任意函數(shù)了 。

def info(func):    def wrapper(*args, **kwargs):  # 指定*args和**kwargs,接收任意參數(shù)        print('[INFO]: 調(diào)用 {}()'.format(func.__name__))        return func(*args, **kwargs)    return wrapper  # 返回@infodef say(arc1):    print('hello {}!'.format(arc1))@infodef todo(x,y):    print(x * y)say('作用于多個(gè)函數(shù)的裝飾器')todo(3,5)#輸出:[INFO]: 調(diào)用 say()hello 作用于多個(gè)函數(shù)的裝飾器![INFO]: 調(diào)用 todo()15

3.6 回調(diào)函數(shù)

簡(jiǎn)單的來(lái)說(shuō),,把一個(gè)函數(shù)作為參數(shù)傳給另一個(gè)函數(shù),,那么這個(gè)函數(shù)就是回調(diào)函數(shù)。這個(gè)被傳入的參數(shù)其實(shí)是函數(shù)指針,,即指向一個(gè)函數(shù)的指針(地址),。

def calc(func,a,b):     #第一個(gè)參數(shù)接收一個(gè)函數(shù)    return func(a,b)def add(x,y):    return x + ydef mul(x,y):    return x * yprint(calc(add,3,5))        #第一個(gè)參數(shù)為函數(shù),后面的兩個(gè)參數(shù)是函數(shù)的參數(shù)print(calc(mul,3,5))        #輸出815

回調(diào)函數(shù)還可以進(jìn)行異步調(diào)用,,即非阻塞調(diào)用,,通常用在多線(xiàn)程或者多進(jìn)程中。

3.7 生成器函數(shù)

生成器函數(shù),,就是說(shuō)定義函數(shù)時(shí),,內(nèi)部帶yield就算生成器函數(shù)。在調(diào)用生成器運(yùn)行的過(guò)程中,,每次遇到 yield 就會(huì)返回 其后的值, 并在下一次執(zhí)行 next() 方法是從當(dāng)前位置繼續(xù)運(yùn)行,。

def scq_func():    for x in range(1,10):        yield x * 2s = scq_func()print(s)       #輸出:<generator object scq_func at 0x0161B510>print(next(s))print(next(s))print(next(s))print(next(s))#輸出:<generator object scq_func at 0x0161B510>2468

以上函數(shù)在執(zhí)行過(guò)程中,遇到y(tǒng)ield就中斷下次又繼續(xù)執(zhí)行,,直到?jīng)]有yield可執(zhí)行了,,再調(diào)用next就會(huì)報(bào)錯(cuò) 。

那該函數(shù)主要的作用是什么呢 ,? 在數(shù)學(xué)中有很多的計(jì)算都是無(wú)限窮盡的(比如自然數(shù)) ,。我們不可能通過(guò)序列去存放,這時(shí)我們就可以使用生成器按照規(guī)則計(jì)算下出一個(gè)數(shù)據(jù),,可以計(jì)算出很大的數(shù) ,。

import sys def fibonacci(n): # 生成器函數(shù) - 斐波那契    a, b, counter = 0, 1, 0    while True:        if (counter > n):             return        yield a        a, b = b, a + b        counter += 1f = fibonacci(10) # f 是一個(gè)迭代器,由生成器返回生成 while True:    try:        print (next(f), end=' ')    except StopIteration:        sys.exit()        #輸出:0 1 1 2 3 5 8 13 21 34 55

3.8 小結(jié)

最后,,我們將上面講的內(nèi)容通過(guò)一張思維導(dǎo)圖來(lái)總結(jié),,具體如下

python到底還有哪些函數(shù)我們還沒(méi)見(jiàn)過(guò)?原來(lái)有這么多實(shí)用的函數(shù)

總結(jié)

最后我們將上面的介紹做個(gè)整體的回顧,,整體涉及到了如下內(nèi)容:

  1. 函數(shù)是什么 ,?
  2. 函數(shù)的組成 。
  3. 函數(shù)如何調(diào)用,?
  4. 函數(shù)可以有哪些返回類(lèi)型 ,?
  5. 函數(shù)中的值傳遞和引用傳遞
  6. 函數(shù)中常見(jiàn)的4種參數(shù)類(lèi)型,。
  7. 函數(shù)中的一些高級(jí)函數(shù) 。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶(hù)發(fā)布,,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多