函數(shù)是代碼重用最基本的部件
定義函數(shù):Python使用def關(guān)鍵字定義函數(shù)
def 函數(shù)名(參數(shù)1,參數(shù)2):
xxx
變量作用域
Python變量作用域一共有4種
L (Local) 局部作用域
E (Enclosing) 閉包函數(shù)外的函數(shù)中
G (Global) 全局作用域
B (Built-in) 內(nèi)建作用域
以 L –> E –> G –>B 的規(guī)則查找哑芹,即:在局部找不到沧烈,便會(huì)去局部外的局部找(例如閉包)鞭衩,再找不到就會(huì)去全局找,再者去內(nèi)建中找
Python中,def/class/lambda中賦值的變量,其作用域?yàn)?strong>局部作用域,且三者的身份相同,故犬性,類中函數(shù)要調(diào)用類中賦值變量,需增加self前綴
要點(diǎn):
1.函數(shù)可直接調(diào)用全局變量
name = 1
def fun():
print(name)
if __name__ == "__main__":
fun()
>>>1
2.函數(shù)中賦值和全局變量同名的變量腾仅,此時(shí)函數(shù)內(nèi)變量為新局部變量乒裆,故使用前需先賦值;在函數(shù)作用域中推励,局部變量覆蓋同名全局作變量鹤耍,但不會(huì)影響全局變量
name = 1
def fun():
print(name)
name = 0
if __name__ == "__main__":
fun()
>>>Traceback (most recent call last):
File "test.py", line 7, in <module>
fun()
File "test.py", line 3, in fun
print(name)
UnboundLocalError: local variable 'name' referenced before assignment
# name此時(shí)為局部變量
name = 1
def fun():
name = 0
print(name)
if __name__ == "__main__":
fun()
>>>0
3.局部作用域中想對(duì)全局變量賦值,或者想在局部作用域中生成全局變量验辞,使用global關(guān)鍵字
# Python執(zhí)行時(shí)稿黄,即使調(diào)用的函數(shù),也會(huì)先執(zhí)行函數(shù)外部的其他語句跌造,再執(zhí)行函數(shù)
# 故fun()執(zhí)行前杆怕,會(huì)先打印1,然后執(zhí)行了fun壳贪,在執(zhí)行print打印name
name = 1
def fun():
global name
name = 0
print(name)
if __name__ == "__main__":
fun()
print(name)
>>>1
>>>0
4.函數(shù)中可以嵌套函數(shù)陵珍,特殊場(chǎng)景為閉包
閉包:引用了自由變量的函數(shù)。這個(gè)被引用的自由變量將和這個(gè)函數(shù)一同存在违施,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外互纯,如下
def A():
param=1
def B():
param1=param
print(param1)
return B
if __name__ == '__main__':
A()()
>>>1
B為A嵌套函數(shù),B中引用外部函數(shù)變量(即上文中自由變量)磕蒲;
調(diào)用函數(shù)A留潦,返回函數(shù)B實(shí)例(返回函數(shù)B即稱閉包),此時(shí)變量param被記住辣往。即A函數(shù)調(diào)用結(jié)束(局部變量函數(shù)調(diào)用后即時(shí)失效)愤兵,param變量依然存在
global和nonlocal
global:函數(shù)中若想修改全局變量,需使用該關(guān)鍵字聲明
nonlocal:允許嵌套def對(duì)其外部函數(shù)中變量賦值(一般只引用)且這個(gè)變量需已在外層被賦值過排吴,而非在嵌套def中初始賦值