函数对象
函数是第一类对象,其含义是函数可以被当做数据处理。
1.引用
def func():
print('from func')
f = func
print(f)
2.当做一个参数传给一个函数
def func():
print('from func')
def foo(m):
print(m)
m()
foo(func)
3.可以当做函数的返回值
def func():
print('from func')
def foo(x):
return x
res = foo(func)
print(res)
res()
4.可以当做容器类型的元素
def func():
print('from func')
l = [func, ]
print(l)
l[0]()
演示个小例子,加深印象~
def pay():
print('pay...')
def withdraw():
print('withdraw...')
def transfer():
prinnt('transfer...')
def check_balance():
print('check_balance...')
def shopping():
print('shopping...')
func_dic={
'1':pay,
'2':withdraw,
'3':transfer,
'4':check_balance,
'6':shopping,
}
while True:
msg = '''
1 pay:
2 withdraw:
3 transfer:
4 check_balance:
5 break:
6 shopping:
'''
print(msg)
choice = input('input your actions>>>:').strip()
if choice == '5': break
if choice not in func_dic:
print('command not exist !')
continue
func_dic[choice]()
将函数作为字典的key放入字典中,输入对应编号即可取到对应的value。
函数嵌套
在定义阶段的嵌套:
def f1():
def f2():
print('from f2')
f2()
f1()
让用户输入半径并选择计算圆的周长还是面积:
from math import pi #导入系统模块获取π
def circle(radius, action = 'area'):
def area():
return pi * (radius ** 2)
def perimeter():
return 2 * pi * radius
if action == 'area':
return area()
elif action == 'perimeter':
return perimeter()
print(circle(5)) # 不输入第二个参数默认为计算面积
print(circle(5, action = 'perimeter'))
调用阶段的函数嵌套
求出用户输入的四个数中最大的数
def max(x, y)
if x > y:
return x
else:
return y
def 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))
名称空间与作用域
1.名称空间
名称空间(namespace)是存在于内存中用来存放变量、函数等名字与绑定关系的地方。
2.名称空间分为三大类
内置名称空间
作用:存放python解释器自带的名字(关键字、函数名等)
生命周期:自打开启动器生效至关闭解释器
例如:len print等
全局名称空间
作用:除了内置名称空间与局部的名称空间,其余的全部是全局名称空间(这么说太模糊了,解释完局部名称空间再回头看)
生命周期:在执行python文件时生效,直至执行文件完毕
例如:以下x, func, y, l, z 变量或函数名称都属于全局名称空间
x = 1
def func():
a = 1
y = 2
l = [1, 2, ]
if 3 > 1:
if 1 > 0:
if 0 < 1:
z = 3
局部名称空间
作用:用于存放函数调用期间函数体产生的名字
生命周期:在文件执行过程如果调用了某个函数才会临时生效,函数执行完毕后失效。
三种名称空间的加载顺序是:
内置--->全局--->局部
名称空间就是用来存放民资与值的绑定关系的,只要涉及到查找名字,一定是从三者之一找到,查找顺序:
从当前所在的位置依次向上查找,若当前所在位置为局部名称空间,则查找顺序为:
局部--->全局--->内置
作用域
域指的是区域、范围,作用域即作用的范围
全局作用域(内置名称空间域全局名称空间):
全局有效,全局存活
局部作用域(局部名称空间)
局部有效,临时存活
len = 100
def func():
len = 1000
print(len)
func()#可以试着注释其中一个或者两个len,看看查找到的len是哪个值
x = 10
def func():
print(x)
x = 1
func()
x = 1
def f1():
def f2():
def f3()
z = 33
print(x)
x = 111
f3()
x = 222
f2()
def bar():
print(x)
f1()
bar()
作用域关系是在函数定义阶段就固定,只要调用函数都需要定义阶段找作用域关系。
x = 1
def f1():
print(x)
f1()
x = 1000
def f2():
print(f1)
x = 111
f1()
f2()
函数对象+作用域
def f1():
def inner():
print('from inner', x)
return inner
f = f1()
print(f)
def bar():
x = 1111111
f()
bar()#打破层级限制,访问嵌套内部函数
x = 1
def foo():
global x #改全局变量
x = 2
foo()
print(x) #在局部名称空间改全局变量,下同:
x = 1
def f1():
def f2():
x = 33445
def f3():
global x
x = 12345
f3()
f2()
f1()
print(x)
在局部如果想修改全局的可变类型数据,不需要借助任何声明,可以直接修改。
在局部如果想修改全局的不可变类型,需要借助global声明,声明为全局的变量就可以修改。
x = [] # 列表是可变类型,字符串 int 都是不可变类型
def f1():
x.append(1)
f1()
pirnt(x)