函數對象:?
函數是第一類對象,即函數可以當做數據傳遞
1 可以被引用
2 可以當做參數傳遞
3 返回值可以是函數? (函數名 不帶() 就是函數名的內存地址,帶括號就是執行函數)
4 可以當做容器類型的元素
def foo():print('foo')def bar():print('bar')dic={'foo':foo,'bar':bar, } while True:choice=input('>>: ').strip()if choice in dic:dic[choice]()
def func(): # func=函數的內地址
print('from func')
age=10
# 1. 可以被引用
# x=age
# print(x,age)
# f=func
# print(f)
# f()
# 2. 可以當作參數傳給另外一個函數
# def bar(x):
# print(x)
# bar(age)
# bar(func)
# 3. 可以當作一個函數的返回值
# def bar(x):
# return x
# res=bar(age)
# print(res)
# res=bar(func)
# print(res)
# 4. 可以當作容器類型的元素
# l=[age,func,func()]
# print(l)
?
利用函數的特性取代多分支的if
def foo():print('foo')def bar():print('bar')dic={'foo':foo,'bar':bar, } while True:choice=input('>>: ').strip()if choice in dic:dic[choice]()
函數的嵌套
函數的嵌套定義:一個函數內部又定義了另一個函數 def f1():def f2():def f3():print('from f3')f3()f2()f1() f3() #報錯 空間與作用域 函數的嵌套調用 :在調用一個函數過程中,內部代碼又調用了其他函數 def max(x,y):return x if x > y else ydef max4(a,b,c,d):res1=max(a,b)res2=max(res1,c)res3=max(res2,d)return res3 print(max4(1,2,3,4)
名稱空間與作用域
什么是名稱空間: 存放名字的地方,三種名稱空間(內置 全局 局部)
名稱空間的加載順序
python test.py
1 python解釋器先啟動,因而首先加載的是:內置空間
2 執行test.py文件,然后以文件為基礎,加載全局名稱空間
3 執行文件的過程中如果調用函數,則臨時產生局部名稱空間
名字的查找順序
局部名稱空間———》全局名稱空間——》內置名稱空間 (在全局無法查看局部的,在局部可以查看全局的)
# max=1 def f1():# max=2def f2():# max=3print(max)f2() f1() print(max)
作用域
#1、作用域即范圍- 全局范圍(內置名稱空間與全局名稱空間屬于該范圍):全局存活,全局有效- 局部范圍(局部名稱空間屬于該范圍):臨時存活,局部有效 #2、作用域關系是在函數定義階段就已經固定的,與函數的調用位置無關,如下 x=1 def f1():def f2():print(x)return f2 x=100 def f3(func):x=2func() x=10000 f3(f1())#3、查看作用域:globals(),locals() LEGB 代表名字查找順序: locals -> enclosing function -> globals -> __builtins__ locals 是函數內的名字空間,包括局部變量和形參 enclosing 外部嵌套函數的名字空間(閉包中常見) globals 全局變量,函數定義所在模塊的名字空間 將局部變量的作用域提升至全局作用域,可以用來在局部修改全局的不可變類型 builtins 內置模塊的名字空間
nonlocal 聲明一個名字是來自于當前層外一層作用域的,可以用來在局部修改外層函數的不可變類型將L 與 E 中的名字統一需要提前定義
!!!名字的查找順序,在函數定義階段就已經固定死了(及在檢測語法是就已經確定了名字的查找順序),與函數的調用位置無關,也就是說無論在任何地方調用函數,都必須回到當初定義函數的位置去確定名字的查找關系
x=111 def outer():def inner():print('from inner',x) # x訪問的時全局名稱空間中xreturn innerf=outer() <function outer.<locals>.inner at 0x00000000021DB6A8> print(f) from inner 222x=222 f() 222 訪問時全局的x已經被重新賦值了x=111 def outer():def inner():print('from inner',x) # x訪問的時全局名稱空間中xreturn innerf=outer() from inner 444 全局被重新賦值為444# x=222 def func():x=333f()x=444func() func->f->outer->x 全局變量 444 from inner 444