In [1]: def add(x, y): # return 除了返回值之外, 還會結束函數, return以後的語句將不會被執行 ...: return x + y ...: print('hahaha') ...: hahaha In [2]: def add(x, y): ...: return x + y ...: print('hahaha') ...: In [3]: ret = add(1, 3) In [4]: ret Out[4]: 4 In [5]: def guess(x): # 因此一個函數能夠有多個return, 執行到哪一個return,就由哪一個return 返回結果並結束函數 ...: if x > 3: ...: return '>3' ...: return '<=3' ...: In [6]: s = guess(3) In [7]: s Out[7]: '<=3' In [8]: s = guess(5) In [9]: s Out[9]: '>3' In [10]: In [10]: def fn(x): ...: for i in range(x): ...: if x > 3: ...: return i ...: else: ...: print('not bigger than 3') ...: In [11]: fn(10) Out[11]: 0 In [12]: fn(3) not bigger than 3 In [13]: In [13]: def fn(): # 若是當函數沒有return 語句的時候, 隱式返回了一個None ...: pass ...: In [14]: ret = fn() In [15]: type(ret) Out[15]: NoneType In [16]: typr(None) --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-16-3565bd08d192> in <module>() ----> 1 typr(None) NameError: name 'typr' is not defined In [17]: type(None) Out[17]: NoneType In [18]: ret == None Out[18]: True
In [19]: def fn(): ...: return 3, 5 ...: In [20]: ret = fn() In [21]: ret # 相似於 封裝 Out[21]: (3, 5) In [22]: x, y = ret # 相似於 解構 In [23]: x Out[23]: 3 In [24]: y Out[24]: 5
In [27]: def fn(): ...: return None ...: In [28]: ret = fn() In [29]: ret == None Out[29]: True In [30]: In [30]: def fn(): ...: return # 返回None, 能夠簡寫爲 return 一般用於結束函數 ...: In [31]: In [31]: def fn(x): ...: if x > 3: ...: return ...: return '<=3' ...: In [32]: fn(5) In [33]: fn(3) Out[33]: '<=3' In [34]:
In [35]: def outter(): ...: def inner(): ...: print('inner') ...: print('outter') ...: inner() ...: In [36]: outter() outter inner In [37]:
In [39]: x = 1 In [40]: def inc(): ...: print(x) # 並未參與到運算中 ...: y = x + 1 # 只讀可見, 不可寫 ...: return y ...: In [41]: inc() 1 Out[41]: 2 In [42]:
In [42]: def fn(): ...: xx = 1 ...: print(xx) ...: In [43]: fn() 1 In [44]: xx --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-44-ce3af7760f12> in <module>() ----> 1 xx NameError: name 'xx' is not defined In [45]: In [45]: def fn2(): ...: peint(xx) ...: In [46]: fn() 1 In [47]: fn2() # 變量的做用域 爲變量同級的做用域, 也就是說 在哪個級別定義的, 在哪個級別就可見 --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-47-e87bcb52744c> in <module>() ----> 1 fn2() <ipython-input-45-ff1e6126d39a> in fn2() 1 def fn2(): ----> 2 peint(xx) 3 NameError: name 'peint' is not defined In [48]:
In [49]: def fn(): ...: xx = 1 ...: print(xx) ...: def inner(): ...: print(xx) ...: inner() ...: In [50]: fn() 1 1 In [51]: In [51]: def fn(): ...: xx = 1 ...: print(xx) ...: print(id(xx)) ...: def inner(): ...: xx = 2 ...: print(id(xx)) ...: inner() ...: print(xx) ...: print(id(xx)) ...: In [52]: fn() 1 9289856 9289888 1 9289856 In [53]:
In [54]: def fn(): ...: xx = 1 ...: print(xx) ...: def inner(): ...: xx = 2 ...: inner() ...: print(xx) ...: In [55]: xx = 1 In [56]: def fn(): ...: global xx ...: xx += 1 ...: In [57]: fn() In [58]: xx Out[58]: 2 In [59]: fn() In [60]: xx Out[60]: 3 In [61]: In [61]: def fn(): ...: global yy ...: yy = 3 ...: In [62]: fn() In [63]: yy Out[63]: 3 In [64]: def fn(): ...: global zz ...: In [65]: zz --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-65-15546de8c3b0> in <module>() ----> 1 zz NameError: name 'zz' is not defined In [66]:
金玉良言: 除非你清楚的知道,global 會帶來什麼, 並明確的知道非global不行,不然不要使用globalpython
In [66]: def counter(): ...: x = 0 ...: def inc(): ...: global x ...: x += 1 ...: return x ...: return inc ...: In [67]: f = counter() In [68]: f() Out[68]: 2 In [69]: f() Out[69]: 3 In [70]: f = counter() In [71]: f() Out[71]: 4 In [72]: x Out[72]: 4 In [73]: f() Out[73]: 5 In [74]: x Out[74]: 5 In [75]: x = 0 In [76]: f() Out[76]: 1 In [77]: x Out[77]: 1
In [79]: def counter(): ...: c = [0] ...: def inc(): ...: c[0] += 1 ...: return c[0] ...: return inc ...: # 函數執行完畢以後,仍有部分函數變量的引用存在 In [80]: f = counter() In [81]: f() Out[81]: 1 In [82]: c = 100 In [83]: f() Out[83]: 2 In [84]: lst = [1] In [85]: id(lst) Out[85]: 140023278144840 In [86]: lst[0] = 2 In [87]: id(lst) Out[87]: 140023278144840 In [88]: f() Out[88]: 3 In [89]: f = counter() In [90]: f() Out[90]: 1 In [91]: f() Out[91]: 2 In [92]:
In [92]: def counter(): ...: x = 0 ...: def inc(): ...: x += 1 ...: return x ...: return inc ...: In [93]: f = counter() In [94]: f() --------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) <ipython-input-94-c43e34e6d405> in <module>() ----> 1 f() <ipython-input-92-91cd34f02038> in inc() 2 x = 0 3 def inc(): ----> 4 x += 1 5 return x 6 return inc UnboundLocalError: local variable 'x' referenced before assignment In [95]: In [95]: def counter(): # 經過 nonlocal 關鍵字,能夠對上級做用域的變量,進行 可讀可寫 ...: x = 0 ...: def inc(): ...: nonlocal x ...: x += 1 ...: return x ...: return inc ...: In [96]: f = counter() In [97]: f() Out[97]: 1 In [98]: f() Out[98]: 2 In [99]:
In [100]: def fn(x=[]): ...: x.append(1) ...: print(x) ...: In [101]: fn() [1] In [102]: fn() [1, 1] In [103]: fn Out[103]: <function __main__.fn> In [104]: fn.__defaults__ Out[104]: ([1, 1],) In [105]: In [105]: fn() [1, 1, 1] In [106]: fn.__defaults__ Out[106]: ([1, 1, 1],) In [107]: fn.__defaults__ = ([], ) In [108]: fn() [1] In [109]: fn.__defaults__ Out[109]: ([1],) In [110]: In [110]: def gn(a=2, b=1): ...: print(a + b) ...: In [111]: gn.__defaults__ Out[111]: (2, 1) In [112]:
全局做用域。何時會銷燬?編程
局部做用域。何時銷燬?bash
In [112]: def fn(aa=[], bb=[]): ...: aa.append(1) ...: bb.append(2) ...: print(aa, bb) ...: In [113]: fn() [1] [2] In [114]: fn() [1, 1] [2, 2] In [115]: fn.__defaults__ Out[115]: ([1, 1], [2, 2]) In [116]: In [116]: def fn(x=0, y=0): # int 是不可變類型 ...: print(id(x)) ...: x = 3 ...: print(id(x)) ...: x = 4 ...: print(id(x)) ...: y = 3 ...: print(x, y) ...: In [117]: fn() 9289824 9289920 9289952 4 3 In [118]: fn.__defaults__ # int 是不可變類型 Out[118]: (0, 0) In [119]:
如何去接解決list的問題?閉包
In [120]: def fn(lst=None): ...: if lst is None: ...: lst = [] ...: lst.append(3) ...: print(lst) ...: In [121]: fn.__defaults__ Out[121]: (None,) In [122]: fn() [3] In [123]: In [123]: In [123]: def fn(lst=[]): ...: print(id(lst)) ...: lst = lst[:] ...: print(id(lst)) ...: lst.append(1) ...: print(lst) ...: In [124]: fn() 140023278495752 140023268626120 [1] In [125]: fn.__defaults__ Out[125]: ([],) In [126]: fn() 140023278495752 140023278218120 [1] In [127]: fn.__defaults__ Out[127]: ([],) In [128]: In [128]: In [128]: def fn(lst=None): ...: if lst is None: ...: lst = [] ...: else: ...: lst = lst[:] ...: lst.append(3) ...: print(lst) ...: In [129]: fn() [] In [130]: fn() [] In [131]: fn.__defaults__ Out[131]: (None,) In [132]: fn(1) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-132-454eedcabd9c> in <module>() ----> 1 fn(1) <ipython-input-128-3bf22a286480> in fn(lst) 3 lst = [] 4 else: ----> 5 lst = lst[:] 6 lst.append(3) 7 print(lst) TypeError: 'int' object is not subscriptable In [133]: fn([1, 2, 3]) [1, 2, 3, 3] In [134]:
mainapp
f1()函數
f2()spa
f3()code
f4()
f5()
main對象
程序調用自身的編程技巧,稱爲 遞歸。遞歸
概括法:經過一類事物的部分對象具備某種性質,推出這類事物的全部對象都具備這種性質的推理方法。
例如,斐波那契數列
fib(n) = 1 if n = 0
fib(n) = 1 if n = 1
fib(n) = fib(n-1) + fib(n-2)
In [146]: def fib(n): ...: if n == 0: ...: return 1 ...: if n == 1: ...: return 1 ...: return fib(n-1) + fib(n-2) ...: In [147]: fib(0) Out[147]: 1 In [148]: fib(1) Out[148]: 1 In [149]: fib(2) Out[149]: 2 In [150]: fib(3) Out[150]: 3 In [151]: fib(4) Out[151]: 5 In [152]: fib(5) Out[152]: 8 In [153]: In [153]: In [153]: def fib(n): ...: return fib(n-1) + fib(n-2) ...: In [154]: fib(4) --------------------------------------------------------------------------- RecursionError Traceback (most recent call last) <ipython-input-154-252d5fa3ed3f> in <module>() ----> 1 fib(4) <ipython-input-153-3e11de167e36> in fib(n) 1 def fib(n): ----> 2 return fib(n-1) + fib(n-2) ... last 1 frames repeated, from the frame below ... <ipython-input-153-3e11de167e36> in fib(n) 1 def fib(n): ----> 2 return fib(n-1) + fib(n-2) RecursionError: maximum recursion depth exceeded In [155]: import sys In [156]: sys.getrecursionlimit() Out[156]: 3000