1、函数对象python
函数是第一类对象:函数名指向的值能够被当作参数传递函数
1.函数名能够被传递spa
def func(): print('from func') f = func #函数名能够被传递,这里用一个变量名赋值 func() #from func print(f) #这里打印的是函数的内存地址 f() #f()等价于 func()
2.函数名能够被当作参数传递给其余函数code
def func(): print('from func') def index(args): print(args) #等价于print(func) 打印函数func内存地址 args() #运行函数func() 执行内部代码 print('from index') index(func) #函数名func当作参数名传递到index函数中 #结果 #<function func at 0x0000001A50EE0E18> #from func #from index
3.函数名能够被当作函数的返回值对象
def index(): print('index') def func(): print('func') return index res = func() #返回值是 index print(res) #打印函数名index的内存地址 res() #调用运行index()函数 #结果 #func #<function index at 0x0000001DB2490E18> #index
4.函数名能够被当作容器类型的参数blog
def func(): print('func') print(func()) #func None l = [1,2,func,func()] print(l) #结果 func None func #为何结果有这个,由于在l调用了函数func(),因此打印一个func [1, 2, <function func at 0x0000009769AF0E18>, None]
2、函数调用 (在一个函数内部调用其余函数,能够将复杂的逻辑简单化)生命周期
def index(): func() print('index') def func(): print('func') index() #调用index()以后,func()已经被定义了,能够被调用
3、名称空间内存
名称空间是什么:就是存放变量名和变量值的内存地址的绑定关系的地方作用域
名称空间的分类:io
1.内置空间名称:python解释器提早给你定义好的名字(已经存放在内置名称空间了)
就是一些内置函数:好比 len()/max()....
2.全局名称空间:文件级别的代码
3.局部名称空间:函数体内建立的名字都属于局部名称空间
def func(): username = 'jason' #这个username是局部名称空间 print(username) func()
总结:生命周期
内置名称空间:只要python解释器已启动立马建立 关闭python解释器的时候内置名称空间自动销毁(针对于python解释器)
全局名称空间:只要你运行py文件的时候会自动建立 py文件程序运行结束自动销毁 (针对于py文件)
局部名称空间:函数被调用的时候建立 函数结束就销毁(针对于函数的调用开始结束)
4、名称空间的查找顺序
注意:先要肯定好你当前在哪(在哪一个空间)
查找顺序
1.若是你如今在全局: 全局 >>>内置 (先从全局找再到内置)
2.若是你如今在局部:局部>>全局>>内置(先从局部找再到全局再到内置)
例题:
局部命名空间:先定位要打印的len属于什么空间,由于它是在函数里面的变量,因此它是局部名称空间,先找局部变量,正好函数里面有一个变量名赋值,因此这个len就从这取值
len = '我是全局名称空间的len' def func(): len = '我是局部名称空间的len' print(len) func()
全局和局部:咱们先来看红色的len,这个len在全局的位置,查找顺序先从全局开始,不会找到函数内部的局部。在全局里面已经有一个定义的len,因此用这个 '我是全局名称空间的len'。而后函数里面的len就和上面的同样了。
len = '我是全局名称空间的len' def func(): len = '我是局部名称空间的len' print(len) print(len) # 我如今站在的是全局的位置 func()
#结果
#我是全局名称空间的len
#我是局部名称空间的len
局部:打印的x在局部位置,在自己函数没有,因此就往上一个找局部,找到有一个x。
def func(): x = 1 def index(): print(x) # 1 return index res = func() x = 999 res()
全局:若是把上一道题的局部x删掉,就要到全局里面找,找到x=999在函数调用以前已经定义了,最后结果就是999
def func(): def index(): print(x) # 999 return index res = func() x = 999 res()
全局:x定位到局部,可是在inner里面找不到,outer里面也找不到,因此x是使用全局,后面的inner在哪里调用,x都是在全局找值
x=111 def outer(): def inner(): print('from inner',x) #from inner 111 return inner f=outer() def func(): x=333 f() func()
总结:函数在定义阶段就已经固定查找名字的顺序了,不会由于函数调用的位置改变而改变
5、做用域
做用域就是做用范围,按照生效范围能够分为全局做用域和局部做用域
全局做用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用,全局有效
局部做用域:局部名称空间、只能在局部范围生效
global和nonlocal
global:在局部修改全局的不可变数据类型
在下面这个若是不是用global,后面x和username打印的全局的值,就是1,jason。若是你使用了global,改变了全局变量的值,在下面设置x = 999,username = 'egon',打印的值也是这个。
nonlocal:局部修改局部(函数嵌套)
若是没有加nonlocal,x在局部找值,x=1。nonlocal 修改了前面x的值,在打印的时候变成2
总结:global:局部修改全局,若是有多个,用逗号隔开
nonlocal:局部修改局部,若是有多个,用逗号隔开