函數的返回值

函數的返回值

 

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]:

1、做用域

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

2、閉包

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]:

一、nonlocal

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]:

全局做用域。何時會銷燬?編程

  • 從新定義
  • del 關鍵字刪除
  • 程序結束推出

局部做用域。何時銷燬?bash

  • 從新定義
  • del 關鍵字刪除
  • 上級做用域被銷燬
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對象

3、遞歸函數   

程序調用自身的編程技巧,稱爲 遞歸。遞歸

概括法:經過一類事物的部分對象具備某種性質,推出這類事物的全部對象都具備這種性質的推理方法。

例如,斐波那契數列

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
相關文章
相關標籤/搜索