函数对象
函數對象
函數是第一類對象:即函數可以被當做數據處理。
def func():
print('from func')
print(func)
<function func at 0x00B46858>
一、函數對象的四大功能
1、函數名可以被引用
def func():
print('from func')
f = func # 函數名被引用
f() # from func
2、函數名可以被當做參數傳遞給其他函數
def func():
print('from func')
def deco(args):
print(args) # <function func at 0x00D66858>
args() # from func
print('from index') # from index
deco(func) # 當做參數傳遞
3、函數名可以當做其他函數的返回值
def deco():
print('from deco')
def func():
print('func')
return deco
res = func() # func
print(res) # <function deco at 0x00CF6858>
res() # from deco
4、函數名可以當做容器類型的元素
def func():
print('from func')
print(func()) # None
l = [1,2,func,func()]
print(l) # [1, 2, <function func at 0x01776858>, None]
def register():
username = input('username>>>:').strip()
pwd = input('password>>>>:').strip()
print(username,pwd)
print('register....')
def login():
print('login...')
def transfer():
print('transfer...')
def shopping():
print('shopping...')
def pay():
print('pay....')
func_msg = """
1 注冊
2 登錄
3 轉賬
4 付款
q 退出
"""
func_dict = {
'1':register,
'2':login,
'3':transfer,
'4':pay,
}
while True:
print(func_msg)
choice = input('請選擇你想要的功能').strip()
if choice == 'q':
break
func = func_dict.get(choice)
if func:
func()
else:
print('你想要的功能暫時沒有')
函數的嵌套調用
函數的調用
在函數內部調用其他函數,是為了使用函數的功能,將復雜的邏輯簡單化。
def index():
func()
print('index')
def func():
print('func')
index()
def my_max(x,y):
if x > y:
return x
return y
def my_max4(a,b,c,d):
res1 = my_max(a,b)
res2 = my_max(res1,c)
res3 = my_max(res2,d)
return res3
print(my_max4(1,6,8,0)) # 8
函數的嵌套
函數的嵌套是為了用戶通過一個函數的操作,實現不同的功能。比如ATM自動取款機。
def outer():
x = 1
print('outer')
def inner():
print('inner')
return inner
res = outer() # outer
res() # inner
func_msg = {
0:'注冊',
1:'登錄',
2:'購物',
}
def all_func(number):
def register():
print('register')
def login():
print('login')
def transfer():
print('shopping')
func_dict = {
0:register,
1:login,
2:transfer,
}
fun_choice = func_dict.get(choice)
fun_choice()
while True:
print(f'請選擇{func_msg}')
choice = int(input('請輸入你的選擇?>>>>').strip())
all_func(choice)
名稱空間與作用域
函數內部的函數只能在函數內部調用,不能在函數外部調用。
def deco():
def func():
print('from func')
func()
func() # name 'func' is not defined
一、名稱空間
簡單來說就是存放名字的地方。
名稱空間就是存放變量名與變量值的內存地址的綁定關系的地方。
要想訪問一個變量的值,必須先去名稱空間中拿到對應的名字,才能夠訪問變量的值
1.1、 內置名稱空間
python解釋器提前給你定義好的名字(已經存放到內置名稱空間中了),如len、print、int
生命周期:只要python解釋器啟動就會生效,關閉python解釋器時失效。
1.2、 全局名稱空間
文件級別的代碼
x = 1
if 1==1:
y == 2
print(y)
while True:
z = 3
x,y,z都會放到全局名稱空間,if for while,無論嵌套多少層,它們內部創建的名字都是全局名稱空間的。
生命周期:py文件執行時生效,在py文件執行結束后失效。
1.3、局部名稱空間
函數體內部創建的名字都屬于局部名稱空間
生命周期:函數被調用的時候生效,函數運行結束失效。
1.4、程序的執行順序(加載順序)
名稱空間的執行順序為:內置——全局——局部
1.5、查找順序
查找順序為:從當前的所在位置開始查找,如果當前所在的位置為局部名稱空間,則順序為:局部——全局——內置
x = 111
def f1():
x = 222
def f2():
x = 333
def f3():
# x = 444
def f4():
# x = 555
print(x)
# x = 777
f4()
x = 777
f3()
f2()
f1() # free variable 'x' referenced before assignment in enclosing scope
# x先從f4函數內部開始找,發現沒有,就到f3函數內部開始找,發現f4里面有一個x = 777,但是要想傳遞給x,必須得先執行f4()函數,f4函數內部沒有x,就會往外部尋找,一直循環,知道報錯。(能看到葡萄但是吃不到葡萄)
函數在定義階段查找名字的順序已經被固定了,不會因為函數的調用位置變化而改變。
x = 111
def outer():
def inner():
print('from inner',x)
return inner
f = outer()
x = 222
f() # from inner 222
# x的查找順序,先在inner函數內部開始查找,發現沒有,之后在外部開始查找,這個外部是x=222
x = 111
def outer():
def inner():
print('from inner',x)
return inner
f = outer()
def func():
x = 333
f()
func() # from inner 111
# x的查找順序,就是outer函數和inner函數執行后,x的查找順序,發現在外部,x=111
x = 111
def outer():
def inner():
print('from inner',x)
x = 666666
return inner
f = outer()
f() # UnboundLocalError: local variable 'x' referenced
# x的查找順序,先從本身開始查找,發現有x=66666,但是取不到。會提示報錯
二、作用域
2.1、全局作用域
全局作用域:全局有效,全局存活,包含內置名稱空間和全局名稱空間。
2.1、局部作用域
局部作用域:局部有效,臨時存儲,只包含局部名稱空間。
2.3、注意點
作用域關系在函數定義階段就已經固定死了,與函數的調用無關。
x = 1
def f1():
print(x) # 函數定義階段,x=1,就已經被固定了。
def f2():
x = 10
f1() # 所以函數無論被如何調用,都是一個整體
f2()
global、nonlocal關鍵字
global在局部修改全局的變量、修改的是不可變數據類型??勺償祿愋蜁詣有薷?,不要用global。
# 可變數據類型可直接在局部修改全局的變量
x = []
def func():
x.append('嘿嘿嘿')
func()
print(x) # ['嘿嘿嘿']
# global 修改局部變量為全局變量
x = 1
username = 'jason'
def func():
global x,username # 將局部變量x,username的值999,'egon',修改為全局變量x,username的值
x = 999
username = 'egon'
func()
print(x) # x = 999
print(username) # username = 'egon'
# nonlocal 修改局部變量為局部變量
def func():
x = 1
def index():
nonlocal x # 將局部變量index函數內部的x的值2,修改為局部變量fun函數的x的值
x =2
index()
print(x)
func()
global:局部修改全局,如果想修改多個,用逗號隔開
nonlocal:局部修改局部,如果想修改多個,用逗號隔開
Never,Never,Never give up.
總結
- 上一篇: 微信开发系列之八 - 微信公众号的地图集
- 下一篇: 流放者柯南全控制台指令 流放者柯南控制台