函数对象、作用域
实例1:通过外部调取内部值
函数对象+作用域(打破函数调用层级,从外部调取内部函数的值)
#正常情况只能通过f1去调用里面函数inner()的值
def f1():
def inner():
print('from inner')
inner()
f1()
#实现外部调取内部函数的输出值
#思路:先调用出内置函数物理地址,再通过物理地址() 再输出内置函数的值
def f1():
def inner():
print('from inner')
return inner
x=f1()
print(x) #这一步调用inner并输出inner物理地址,返回的是inner的物理地址<function f1.<locals>.inner at 0x05A5E7C8>
x() #最后 通过物理地址加(),调取函数值
#进而可以实现在其他函数体中调取inner()函数
def bar():
x()
bar()
实例2:银行转账
#正常的取款方式:
def qukuan():
print('1:取款')
def zhuanzhang():
print('2:转账')
def zhifu():
print('3:支付')
def yuer():
print('4:查询余额')
msg ='''
1.取款
2.转账
3.支付
4.查询余额
5.退出
'''
while True:
print(msg)
choice=input("请选择数字1,2,3,4:")
if choice == '5':
break
elif choice == "1":
qukuan()
elif choice == "2":
zhuanzhang()
elif choice == "3":
zhifu()
elif choice == "4":
yuer()
else:
print('none')
结合函数改进版:
def withdraw():
print('1:取款')
def transfer():
print('2:转账')
def pay():
print('3:支付')
def check_balance():
print('4:查询余额')
def quit():
print('5.退出')
operate={
'1':withdraw, #把函数名当成变量名去用,通过调用key值拿到每个功能的函数名,通过 函数名+() 取出输出结果
'2':transfer,
'3':pay,
'4':check_balance,
'5':quit
}
while True:
msg = '''
1.取款
2.转账
3.支付
4.查询余额
5.退出
'''
print(msg)
choice=input("请选择数字1,2,3,4:")
if choice == '5':break
if choice not in operate: #in对于字典来说判断的是key
print('里面没有对应的功能,请重新选择')
continue
operate[choice]() #operate[choice]取到的值是value指,即qukuan、zhuanzhang等等
#思路:
# if循环选择是重复性的操作,而且后面随着新需求的增加,还需要手动去增加很过条目,比较麻烦
# 考虑如何让用户的选择由原来手动的if一一对应1,2,3,4,5 ,改变成让系统自动去对应上每个功能的函数名,最后输出函数结果
#本质就是如何实现在外部调取函数名,从而实现用户的选择输入后,打印相应的函数体结果
global在函数内部改动全局:
x=6
def foo():
# global x
x=3
foo()
print(x)
#不加global默认输出》》》6,因为print和x=6属于同一层级,全局名称空间
#x=3只在函数foo里面被调用,属于局部名称空间
#如果加了global 输出是》》》3,global声明是全局的,所以当x=3时,全局的6会被改掉
#nonlocal可以改动上一层函数f2的值
def f1():
def f2():
x=2222
def f3():
nonlocal x
x=666666
f3()
print(x)
f2()
f1()
#局部如果要修改全局的可变类型,不需要借助任何声明,可以直接修改
#在局部如果想要修改全局的不可变类型,需要借助global声明,声明为全局的变量就可以直接修改了
x=[]
def f1():
x.append('a')
f1()
print(x) #输出为 ['a']