Python函數的返回值與嵌套函數

1.什麼是返回值

  • 返回值指的是函數返回的結果;
  • return執行完畢後面的語句將不會再執行;
def add(x, y):
    print(x, y)   #輸出:10 20
    return x + y   # 返回值, return之後的語句將不會再執行
    print(x)
    print(y)
add(10,20)
  • 若是一個函數裏面有兩個return,前面return執行完畢,後面的return也不會執行;
def add(x, y):
    print(x, y)    # 輸出:1 2
    return x + y   # 函數體內,碰到return語句,函數執行完畢,以後的語句將不會再執行
    return x - y   # 不會再次執行
add(1,2)

2.函數的隱式返回和顯示返回

  • Python函數都有返回值,若是有return語句,是顯式返回;
  • 若是沒有return語句,默認返回None,是隱式返回;

3.函數多值返回

  • 若是返回多個值經過逗號分開,會把值進行壓縮,封裝成一個元組;
def get_data(x,y,z):
    return x + 1, y + 1, z + 1
print(get_data(1,2,3)) # 獲得的是一個元組(2, 3, 4)
  • 若是返回一個列表,獲得的就是一個列表;
def get_data(x,y,z):
    return [x + 1, y + 1, z + 1]
print(get_data(1,2,3))  # 獲得的是一個列表[2, 3, 4]

4.什麼是嵌套函數

def outer_function():
    # 內部函數
    def inner_function():
        print("inner_function")  # 輸出:inner_function
    print("outer_function")      # 輸出:outer_function
    # 內部調用
    inner_function()
outer_function()
# 注意:inner_function函數只能在outer_function函數內部調用,沒法再outer_function函數外部被調用
  • 嵌套函數的內部函數只能在包含它的函數的直接父級調用,也就是隻能在包含它的外部函數中調用;
  • 嵌套函數層數不宜過深,通常3層之內便可,太深不夠直觀,容易形成代碼混亂;

5.函數做用域

  • 做用域指的是,一個標識符的做用範圍就是這個標識符的做用域;
  • 在函數裏面定義的變量(即局部做用域)只能在函數體內部被訪問,函數外部不能訪問;
def add(x, y):
    z = 100
    print(x, y , z)  #輸出:1 2 100
add(1,2)
print(z)  #報錯:NameError: name 'z' is not defined
  • 在函數外部定義的變量(即全局做用域)能在函數體外部被訪問,也能在函數體內部被訪問;
z = 100
def add(x, y):
    print(x, y, z)# 輸出:1 2 100
add(1, 2)
print(z)  # 輸出:100

6.函數的閉包

  • 閉包:內部函數引用了外部函數的變量,這就是閉包的定義;
  • 若是函數體想訪問變量,只能在變量定義以後才能訪問;
# 例1
x=5
def add():
    y = x + 1
    print(y)  #輸出:6
add()

# 例2
x=5
def add():
    x = x + 1  # 報錯:local variable 'x' referenced before assignment
add()

# 報錯緣由分析:
# 在例1中,函數內部引用的x爲函數外部的x, 所以x的值爲5
# 在例2中,函數內部從新定義了x的值,那麼整個函數內部都會使用這個內部x,
# 所以在運算x + 1的時候,x尚未完成定義就被引用了,這裏的x引用的必定是內部正在定義的 x,不是函數外部的 x=5這個x;


# 例3:
x=5
def add():
    print(x) # 這裏的x引用的是x = 1的x,可是執行print(x)時,x尚未被定義,因此報錯:local variable 'x' referenced before assignment
    x =  1
add()
  • 若是要訪問函數體內部的函數,能夠先把內部函數的函數名做爲外部函數的返回值,把外部函數的引用賦值給變量,再調用變量;
# 例4:
def outer_function():
    x = 100
    def inner_function():
        print(x)        # 內部函數引用了外部函數的自由變量  輸出:100
    return inner_function
ret = outer_function()
ret()

7.關鍵字

  • global關鍵字:能夠指定變量爲全局變量,可是global關鍵字會污染全局變量,也就是會覆蓋以前全局變量的值,因此最好慎用;
x=1
def add():
    global x  # 使用global關鍵字,指定x的引用全局的x變量
    x = x + 1
    print(x)  #輸出:2
add()

x = 100
def foo():
    global x  # x被聲明瞭全局變量
    x = 10
    x += 1
    print(x)  # x的值爲11
foo()
print(x)      # 輸出x的值爲:11,本來這裏應該引用的是全局變量x = 100 的,所以global關鍵字污染了全局變量 x
  • nonlocal關鍵字:能夠申明內部函數的變量引用的是外部函數變量的值(做用域在外部函數),不是全局做用域的值,所以不會污染全局做用域;
def outer_function():
    x = 100
    def inner_function():
        x = x + 1       # 這樣會報錯,函數內部從新定義了x的值,可是尚未完成定義就被引用了
        print(x)
    return inner_function
ret = outer_function()
ret()


def outer_function():
    x = 1
    def inner_function():
        nonlocal x   # 使用nonlocal關鍵字聲明x 爲外層函數的x的值
        x = x + 1    #因此這裏使用的x 是外層函數的x
        print(x)   #輸出:2
    return inner_function
ret = outer_function()
ret()

8.函數默認值的做用域

  • 同一個函數的生命週期相同,函數的默認值會綁定在函數的整個生命週期上,不會由於函數內部對默認值的操做而發生改變;
def add(lst = []):
    lst.append('hello')
    print(lst)
add() # 輸出:['hello']
print('id={}'.format(id(add)))   # 函數對象的id值不變,調用的是同一個函數  id=1837000
add() # 輸出['hello', 'hello']
print('id={}'.format(id(add)))   # 函數對象的id值不變,調用的是同一個函數  id=1837000

# 查看函數的位置參數的默認值
print(add.__defaults__)    #輸出:(['hello', 'hello'],)

# 查看函數的關鍵字參數的默認值
print(add.__kwdefaults__)  #輸出:None
  • 可使用淺拷貝copy(簡寫[:])來清空默認值,那每次調用函數,默認值都爲初始值;
def add(lst = []):
    lst = lst[:]
    lst.append('hello')
    print(lst)
add() # 輸出:['hello']
add() # 輸出:['hello']
  • 也能夠經過參數值判斷來給默認值從新賦值,那每次調用函數,默認值都爲初始值;
def add(lst=None):
    if lst is None:
        lst = []
    lst.append(1)
    print(lst)
    
add()    # 輸出:[1]
print(add.__defaults__)  # 輸出: (None,)

add([1, 2, 3])    # 輸出: [1, 2, 3, 1]
print(add.__defaults__)  # 輸出:(None,)

add([4, 5, 6])     # 輸出:[4, 5, 6, 1]
print(add.__defaults__)    # 輸出:(None,)

9.函數銷燬

def add():
    print('add')
del add
add()
  • 能夠經過 del 函數名 的方式來刪除函數,再調用函數時,就會報錯不存在;

參考:俠課島(9xkd.com)Python同窗計劃閉包

相關文章
相關標籤/搜索