python之路 函数进阶
(一)python中函数运行的过程
python解释器开始执行之后,就在内存中开辟了一块内存空间。每当遇到一个变量的时候,就把变量名和变量值之间的对应关系记录下来。但是当遇到函数的时候解释器只是象征性的将函数名读入到存,表示知道这个函数存在了,对于函数内部的变量和逻辑解释器根本不关心。等到函数调用的时候,python解释器会再开辟一块空间来存储这个函数里的内容,这个时候才开始关注函数里面有哪些变量,而函数中的变量会存储在新开辟的内存空间中,函数中的变量只能在函数内部使用,并且会随着函数的执行完毕,这块内存中的所有内容也会被清空。我们给这个“存放名字和值得关系”的空间起了一个名字--------叫做命名空间。
(二)命名空间
首先,命名空间的本质就是存放名字与值的绑定关系
命名空间一共分为三种
内置命名空间:python解释器运行开始,就已经创建,内置命名空间存放了很多python为我们提供的方法
全局命名空间:代码运行开始,创建的存储“变量与值得关系”的空间叫全局命名空间
局部命名空间:在函数运行过程中临时开辟的空间叫局部命名空间。
三种命名空间的加载与取值顺序
加载顺序: 内置命名空间-----》全局命名空间-------》局部命名空间
取值顺序:局部命名空间------》全局命名空间------》内置命名空间
(三)作用域
作用域就是作用范围,按照生效范围可分为全局作用域和局部作用域。
全局作用域包含内置名称空间和全局名称空间,在整个文件的任意位置都能被引用全局有效
局部作用域包含局部名称空间,只能在局部生效。
globals 和 locals 方法
#在全局调用
print(globals())
print(locals())
#在局部调用globals和locals def func(): a = 12 b = 20 print(locals()) print(globals()) func()
global 关键字
#global关键字的作用是声明变量的作用域 a = 10 def func(): global a a = 20 print(a) func() print(a) global关键字的作用是声明变量的作用域
(四)函数的嵌套
#函数的嵌套 def f1(): def f2(): def f3(): print("in f3") print("in f2") f3() print("in f1") f2() f1()
这里稍微补充三元运算
m = x if x>y else y
如果x>y返回x,否则返回y。
nonlocal关键字
nonlocal是用来修改嵌套作用域中的变量,类似于global一样,只需要在嵌套函数中声明变量名即可,但是这个变量名是必须已经存在的,并且内部函数声明nonlocal变量之前不能再出现同名变量,否则就会报错,如果要修改的变量在作用域中找不到,那么不会继续到全局或内置作用域中查找。注意:内部函数只能在上一层函数中生效
def f1(): a = 1 def f2(): nonlocal a a = 2 f2() print('a in f1 : ',a) f1()
(五)闭包函数
def func(): name = 'eva' def inner(): print(name)
在函数内部定义的函数称为内部函数
闭包函数:
内部函数包含对外部作用域而非全局作用域变量的引用,该内部函数称为闭包函数。由于作用域的关系,在函数外部是不能调用函数内部的函数的,这个时候需要将函数名return,这是闭包函数的常用方法。
def func(): name = 'eva' def inner(): print(name) return inner f = func() f()
判断是否是闭包函数的方法—closure—
#输出的__closure__有cell元素 :是闭包函数 def func(): name = 'eva' def inner(): print(name) print(inner.__closure__) return inner f = func() f() #输出的__closure__为None :不是闭包函数 name = 'egon' def func2(): def inner(): print(name) print(inner.__closure__) return inner f2 = func2() f2()
闭包函数获取网路应用
from urllib.request import urlopen def index(): url = "http://www.baidu.com" def get(): return urlopen(url).read() return get xiaohua = index() content = xiaohua() print(content) 闭包函数获取网络应用
(六)函数名的本质:(相当于普通变量的作用)
函数名的本质就是函数的内存地址。
1,函数名可以被引用
2,函数名可以被当做容器类型的元素。
3,可以当做函数的参数和返回值。
小结:三种命名空间:内置,全局和局部。函数嵌套:定义在函数内部的函数无法再全局被调用。函数名的本质相当于变量,保存了函数的内存地址。闭包函数:内部函数包含对外部作用域而非全局作用域变量的引用,称为闭包函数。