函数 对象,嵌套,名称空间作用域
一.函数的对象
函数是第一类对象:函数名对应的值(函数体代码)可以被当作参数传递
1.函数名可以被传递(类似变量)
name = 'waller' ures_name = name # 变量名的传递 print(ures_name) # >>> waller def func(): print('name is waller') print(func) # 打印的是函数体代码的内存地址 <function func at 0x000002EF3AA02EA0> print(id(func)) # 打印的是函数名在内存里的地址 3226504015520 f = func # func对应的函数内存地址也赋值给f print(f) # 打印的是函数体代码的内存地址 <function func at 0x000002EF3AA02EA0>
f() # 调用函数,等价与func()
2.函数名可以被当作参数传递给其他函数
def func(): print('from func') def info(regs): print(regs) # <function func at 0x000001A378C62EA0> regs() # from func print('from info') # from info info(func)
3.函数的名可以被当作函数的值被返回
def func(): print('from func') def info(): print('from info') return func info() # >>> from info 是打印函数运行的结果,并且由返回值可接收 res = info() # >>> from info # 函数的返回值赋值给变量 res print(res) # >>> <function func at 0x000002C27E772EA0> # 等价于 print(func) res() # >>> from func # 等价于 func()
4.函数名可以当作容器类型数据里的元素
def func(): print('from func') print(func()) # 优先运行func()函数,运行结果是from func,有返回值None被print打印了出来9 l = [1,2,func,func()] # 容器类型数据是把func()函数的 返回值 放入其中,而不是函数运行结果 print(l) # >>> [1, 2, <function func at 0x0000024143502EA0>, None]
二.函数嵌套
在函数内部调用其他函数,可以使复杂的逻辑简单化
def my_max(x,y): # 定义可以比较两个数大小的函数 if x > y: return x return y # print(my_max(2,5)) # >>> 打印出函数运行的返回值 def my_max1(a,b,c,d): res1 = my_max(a,b) # 接收两个数比较后的返回值 res2 = my_max(res1,c) res3 = my_max(res2,d) return res3 # 接收最终的返回值 print(my_max1(2,4,6,8)) # >>> 8 # 打印出四个数比较大小的返回值
三.名称空间
存放变量名的地方,存放的使变量名与变量地址绑定关系的地方
要想访问一个值,必须要到名称空间找到变量名才能访问到变量值
名称空间分类:
1.内置名称空间:
python解释器提前定义好的名字存在了内置名称空间(len,max,print,range...)
2.全局名称空间:
文件级别的代码,一般是程序员按照变量名命名规范所起的变量名
3.局部名称空间:
函数体内创建的变量名都属于局部名称空间
生命周期:
1.内置名称空间:python解释器启动创建,python解释器关闭自动销毁
2.全局名称空间:右键运行py文件创建,py文件运行完毕自动销毁
3.局部名称空间:函数调用时创建,函数运行结束立即销毁(动态创建,动态销毁)
查找顺序:
先确定当前位置(*****):
如当前位置在全局:全局 >>> 内置
如当前位置在局部;局部 >>> 全局 >>> 内置
函数在定义阶段名字的查找顺序就已经确定了,不会应为函数的调用位置变化而改变(*****)
name = '全局名称空间' def func(): name = '局部名称空间' print(name) func() # >>> 局部名称空间 print(name) # >>> 全局名称空间 name = '全局名称空间' def func(): print(name) func() # >>> 全局名称空间
# 变量名先定义再调用 def index(): print(x) x = 666 index() # 报错
def index(): x = 10 print(x) def index2(): print(x) index() # >>> x index2() # 报错 并行的函数无法交叉查找变量名
x=111 def outer(): def inner(): print('from inner',x) # 函数在定义阶段名字的查找顺序就已经确定了 return inner f=outer() def func(): x=333 f() # 不会应为函数的调用位置变化而改变 func() # >>> from inner 111
作用域
全局作用域:全局生效
局部作用域:局部生效
global:局部修改全局,如修改多个,用逗号隔开
nonlocal:局部修改局部,如修改多个,用逗号隔开
# 局部修改全局 name = 'waller' age = 20 def func(): global age,name # 声明 age = 22 name = 'wong' print(name,age) func() # wong 22 print(name) # wong print(age) # 22
# 局部修改局部 def func(): x = 1 def info(): nonlocal x x = 2 info() print(x) func() # >>> 2