日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【函数】02、函数进阶

發布時間:2025/3/21 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【函数】02、函数进阶 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、函數的返回值

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 In?[4]:?def?add(x,?y): ???...:?????return?x+y ???...:? In?[5]:?add(1,?2) Out[5]:?3 In?[8]:?def?add(x,?y): ???...:?????return?x+y ???...:?????print(x+y) ???...:????? In?[9]:?add(1,?2) Out[9]:?3 In?[16]:?def?add(x,?y): ????...:?????return?"abc",?x+y ????...:?????return?x+y ????...:????? In?[17]:?add(1,?2) Out[17]:?('abc',?3) ??? In?[18]:?def?add(x,?y): ????...:?????return ????...:? ????...:????? In?[19]:?add(1,?2) In?[20]:?a?=?add(1,?2) In?[21]:?a In?[22]:?type(a) Out[22]:?NoneType In?[25]:?def?add(x,?y): ????...:?????return?None ????...:? In?[26]:?add(1,?2) In?[27]:?type(add(1,?2)) Out[27]:?NoneType


關鍵字:return

? ???return只能出現在函數中,可以返回任何對象,可以作為元祖變相的返回多個值

? ?? 所有函數都有返回值,如果沒定義return則默認返回值None

?????return語句除了返回值之外還會結束函數

??? 1個函數可以有多個return語句,但只會執行一個


二、作用域

1、函數嵌套

??函數可以嵌套定義

1 2 3 4 5 6 7 8 9 10 In?[28]:?def?outter(): ????...:?????def?inner(): ????...:?????????print('inner') ????...:?????print('outter') ????...:?????inner() ????...:????? In?[29]:?outter() outter inner


2、作用域

???作用域是一個變量的可見范圍

?? 函數內部是一個局部作用域,外面叫全局作用域

?? 不同作用域變量不可見,但是上級作用域的變量對下級只讀可見

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 In?[32]:?x?=?1 In?[33]:?def?inc(): ????...:?????x?+=?1???#?x此時是局部變量,不能直接使用全局作用域的變量 ????...:????? In?[34]:?inc() --------------------------------------------------------------------------- UnboundLocalError?????????????????????????Traceback?(most?recent?call?last) <ipython-input-34-ae671e6b904f>?in?<module>() ---->?1?inc() <ipython-input-33-661b9217054c>?in?inc() ??????1?def?inc(): ---->?2?????x?+=?1 ??????3? UnboundLocalError:?local?variable?'x'?referenced?before?assignment In?[40]:?x?=?1 In?[41]:?def?fn(): ????...:?????print(x)??? ????...:????? In?[42]:?fn()????#?為什么這里能打印出來,不拋出錯誤呢 1


變量的作用域為定義此變量的作用域:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 In?[43]:?def?fn(): ????...:?????name?=?"xxj" ????...:?????print(name) ????...:????? In?[44]:?fn() xxj In?[45]:?name --------------------------------------------------------------------------- NameError?????????????????????????????????Traceback?(most?recent?call?last) <ipython-input-45-18697449d7c4>?in?<module>() ---->?1?name NameError:?name?'name'?is?not?defined


上級作用域對下級作用域是只讀可見的

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 In?[46]:?def?fn(): ????...:?????xx?=?1 ????...:?????print(xx) ????...:?????def?inner(): ????...:?????????print(xx) ????...:?????inner() ????...:????? In?[47]:?fn() 1 1 In?[48]:?def?fn(): ????...:?????xx?=?1 ????...:?????print(xx) ????...:?????def?inner(): ????...:?????????xx?=?2 ????...:?????????print(xx) ????...:?????inner() ????...:?????print(xx) ????...:????? In?[49]:?fn() 1 2 1


global關鍵字能且只能引用全局作用域中的變量;引用后的變量能讀寫

如果全局作用域有此變量名,則引用,

沒有則需要定義,定義后此作用域和全局作用域中可見;不定義則會報錯,

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 In?[53]:?xx?=?1 In?[54]:?def?fn(): ????...:?????global?xx????#?global關鍵字能顯式的提升1個變量的作用域 ????...:?????xx?+=?1 ????...:????? In?[55]:?fn() In?[56]:?xx Out[56]:?2 In?[57]:?fn() In?[58]:?xx Out[58]:?3 In?[68]:?xxj --------------------------------------------------------------------------- NameError?????????????????????????????????Traceback?(most?recent?call?last) <ipython-input-68-bc382da45e82>?in?<module>() ---->?1?xxj NameError:?name?'xxj'?is?not?defined In?[69]:?def?fn(): ????...:?????global?xxj??#?如果此變量沒有定義,則此提升變量作用域沒有意義? ????...:????? ????...:????? In?[70]:?fn() In?[71]:?xxj --------------------------------------------------------------------------- NameError?????????????????????????????????Traceback?(most?recent?call?last) <ipython-input-71-bc382da45e82>?in?<module>() ---->?1?xxj NameError:?name?'xxj'?is?not?defined


? 除非你清楚的知道global會帶來什么,并且明確的知道沒有global不行的話,否則不要用global;就是不建議使用global關鍵字


3、默認參數的作用域

函數也是對象,參數是函數對象的屬性,所以函數參數的作用域伴隨函數整個生命周期

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 In?[92]:?def?fn(xy=[]): ????...:?????xy.append(1) ????...:?????print(xy) ????...:????? In?[93]:?fn() [1] In?[94]:?fn() [1,?1] In?[95]:?fn() [1,?1,?1] In?[96]:?fn.__defaults__?????#?函數默認參數的值保存在函數__defaults__屬性中 Out[96]:?([1,?1,?1],) In?[98]:?fn() [1,?1,?1,?1] In?[100]:?fn.__defaults__ Out[100]:?([1,?1,?1,?1],)

??當使用可變類型數據作為默認參數默認值時,需要特別注意。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 In?[105]:?def?fn(x=0,?y=0): ?????...:?????x?=?1??#?賦值即定義 ?????...:?????y?=?2 ?????...:?????print(x) ?????...:?????print(y) ?????...:????? In?[106]:?fn.__defaults__ Out[106]:?(0,?0) In?[107]:?fn() 1 2 In?[108]:?fn.__defaults__ Out[108]:?(0,?0)

解決方案:

? 使用不可變類型作為默認值

? 函數體內不改變默認值

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 In?[109]:?def?fn(lst=None):?????#?如果傳入的參數是非None,那么改變了傳入參數; ?????...:?????if?lst?is?None: ?????...:?????????lst?=?[] ??????????????else: ??????????????????lst?=?lst[:] ?????...:?????lst.append(3) ?????...:?????print(lst) ?????...:????? In?[110]:?fn.__defaults__ Out[110]:?(None,) In?[111]:?fn() [3] In?[112]:?fn.__defaults__ Out[112]:?(None,) In?[113]:?def?fn(lst=[]): ?????...:?????lst?=?lst[:]????#?淺拷貝 ?????...:?????lst.append(2)???#?無論如何不修改傳入參數 ?????...:?????print(lst) ?????...:????? In?[114]:?fn.__defaults__ Out[114]:?([],) In?[115]:?fn() [2] In?[116]:?fn.__defaults__ Out[116]:?([],)

??通常如果使用一個可變參數作為默認參數時,會使用None來代替


4、命名空間與LEGB

?1)命名空間?

?? ? ? 理解Python的LEGB原則是理解Python命名空間的關鍵,而理解Python的命名空間又是理解Python中許多語法規定的關鍵。所以,Python的LEGB原則就成為Python中一個非常核心的內容

白話一點講:命名空間是對變量名的分組劃分
? ? ? ?不同組的相同名稱的變量視為兩個獨立的變量,因此隸屬于不同分組(即命名空間)的變量名可以重復。
命名空間可以存在多個,使用命名空間,表示在該命名空間中查找當前名稱。


? ? ? ?命名空間表示變量的可見范圍,一個變量名可以定義在多個不同的命名空間,相互之間并不沖突,但同一個命名空間中不能有兩個相同的變量名。

比如:兩個叫“張三”的學生可以同時存在于班級A和班級B中,如果兩個張三都是一個班級,那么帶來的麻煩復雜很多了,在Python中你不能這么干。

? ? ??在Python中用字典來表示一個命名空間,命名空間中保存了變量(名字)和對象的映射關系,在Python中命名空間出現在哪些地方呢?有函數范圍內的命名空間(local),有模塊范圍內的命名空間(global),有python內建的命名空間(built-in),還有類對象的所有屬性組成的命名空間

Python一切皆對象,所以在Python中變量名是字符串對象

例如:

1 In?[25]:?a=10

? ? ? 表示建立字符串對象a與Number對象10之間的對應關系。由于這是一種映射關系,所以,可以使用鍵-值的形式來表示,即{name : object}
前面已經說過,命名空間是對變量名的分組劃分,所以,Python的命名空間就是對許多鍵-值對的分組劃分,即,鍵值對的集合,因此:

Python的命名空間是一個字典,字典內保存了變量名稱與對象之間的映射關系


?2)命名空間的生命周期

? ? ? ?所有的命名空間都是有生命周期的,對于python內建的命名空間,python解析器啟動時創建,一直保留直至直python解析器退出時才消亡。而對于函數的local命名空間是在函數每次被調用的時候創建,調用完成函數返回時消亡,而對于模塊的global命名空間是在該模塊被import的時候創建,解析器退出時消亡。


?3)作用域

??一個作用域是指一段程序的正文區域,可以是一個函數或一段代碼。

?一個變量的作用域是指該變量的有效范圍。Python的作用域是靜態作用域,因為它是由代碼中得位置決定的,而命名空間就是作用域的動態表現。

函數定義了本地作用域,而模塊定義了全局作用域:

? ? ? ?每個模塊都是一個全局作用域,因此,全局作用域的范圍僅限于單個程序文件

? ? ???每次對函數的調用都會創建一個新的本地作用域,賦值的變量除非聲明為全局變量,否則均為本地變量

? ? ? ?所有的變量名都可以歸納為本地,全局或內置的(由__builtin__模塊提供)

? ? ??

?4)LEGB原則

LEGB含義解釋:
? ? ? ?L-Local(function);函數內的名字空間
? ? ? ?E-Enclosing function locals;外部嵌套函數的名字空間(例如closure)
? ? ? ?G-Global(module);函數定義所在模塊(文件)的名字空間
? ? ? ?B-Builtin(Python);Python內置模塊的名字空間,
builtin作用域,對應builtin命名空間,python內部定義的最頂層的作用域,在這個作用域里面定義了各種內建函數:open、range、xrange、list等等??? ??

?前面講到,Python的命名空間是一個字典,字典內保存了變量名與對象之間的映射關系

因此,查找變量名就是在命名空間字典中查找鍵-值對
Python有多個命名空間,因此,需要有規則來規定,按照怎樣的順序來查找命名空間LEGB就是用來規定命名空間查找順序的規則。

??LEGB規定了查找一個名稱的順序為:local-->enclosing function locals-->global-->builtin


三、閉包

當一個函數結束了,函數的內部部分變量引用還存在,這就叫閉包

外層函數主要為內層函數提供環境

定義在外層函數內,卻由內層函數引用的變量,在外層函數返回時,如果外層函數返回的值是內層函數,再次調用內層函數時,會記憶下內層函數調用的外層函數的變量。


python的閉包可以使用可變容器實現,這也是python2唯一的方式

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 In?[91]:?def?counter(): ????...:?????c?=?[0] ????...:?????def?inc(): ????...:?????????c[0]?+=?1 ????...:?????????return?c ????...:?????return?inc ????...:? In?[92]:?type(counter) Out[92]:?function In?[93]:?type(counter()) Out[93]:?function In?[94]:?type(counter()()) Out[94]:?list In?[95]:?f?=?counter() In?[96]:?f() Out[96]:?[1] In?[97]:?f() Out[97]:?[2] In?[98]:?f() Out[98]:?[3]


nonlocal關鍵字:

??nonlocal關鍵字能且只能引用外部函數作用域中已存在的變量(不能在自己的作用域中定義);引用后的變量能讀寫

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 In?[102]:?def?counter(): ?????...:?????x?=?0 ?????...:?????def?inc(): ?????...:?????????nonlocal?x ?????...:?????????x?+=?1 ?????...:?????????return?x ?????...:?????return?inc ?????...:? In?[103]:?f?=?counter() In?[104]:?f() Out[104]:?1 In?[105]:?f() Out[105]:?2 In?[106]:?f() Out[106]:?3


四、遞歸函數

? ??函數體內調用自身的函數?? ? ??

? ??遞歸函數需要有合適的退出條件,否則就成了死循環;?遞歸需要邊界條件,遞歸前進段和遞歸返回段?

? ? 在python中為了保護解釋器,遞歸深度最大為1000

? ? python中應盡量避免遞歸,效率低(能轉化為迭代盡量轉化為迭代)??

1 2 3 4 5 6 7 8 9 10 11 12 13 In?[2]:?def?fib(n): ???...:?????if?n?==?0: ???...:?????????return?1 ???...:?????if?n?==?1: ???...:?????????return?1 ???...:?????return?fib(n-1)?+?fib(n-2) ???...:? In?[3]:?fib(5) Out[3]:?8 In?[4]:?fib(6) Out[4]:?13
















本文轉自xiexiaojun51CTO博客,原文鏈接:?http://blog.51cto.com/xiexiaojun/1934142,如需轉載請自行聯系原作者








總結

以上是生活随笔為你收集整理的【函数】02、函数进阶的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。