函数的名称空间及嵌套和闭包
函数的名称空间及嵌套和闭包
函数的名称空间:名称空间分为三种,分别是内置名称空间、全局名称空间以及局部名称空间。
内置名称空间:就是内置函数方法,解释器一启动就加载在里面的方法。
全局名称空间:在组代码中,没有缩进的名称变量或函数方法,就是全局名称空间。
被定义好的全局名称空间可以在代码中的任何地方被使用。
x = 1 def funcname(): pass ##这里的x = 1和函数funcname就是全局名称空间。
局部名称空间:就是函数内部定义的名称空间,只能被该函数内部使用。
def funcname(): y = 1 #这个变量y就只能被函数funcname使用。 print(y)
作用域:先局部在全局,最后内置。
全局作用域:没有缩进的变量,是全局。当局部没有值时,局部变量可以调取全局的值。
x = 1 def foo(): print(x) foo()
局部作用域:局部有值,就使用局部的值,局部没有再去全局。
x = 1 def foo(): x = 2 print(x) foo()
当两个函数的调用,需要先定义再调用,否者在全局中,没有被定义的函数被调用是会报错的。
######### 正常调用 def foo(): print("form foo") bar() def bar(): print("form bar") foo() #都有被定义,调用不会有问题 ######### 不正常调用 def foo(): print("form foo") bar() foo() # 因为foo中调用bar,但在调用foo时bar没有被定义,所以报错 def bar(): print("form bar")
名称空间的查询:
在全局中查询全局globals和局部locals的结果都是全局的值。
在局部中查询全局globals是全局的值,查询局部locals的值是局部的值。
x = 1 def func(): print("form func") x = 2 print(locals()) #在局部查局部,x的结果是2 print("全局",globals()) #在局部查全局的,x的结果是1 print(globals()) #globals 全局, 可以看到里面有x的值和函数func,这就意味着在全局可以使用x的值和函数func func() print(locals()) #在全局查局部的结果是一样的。
函数的嵌套:
函数的嵌套分为函数的嵌套调用和函数的嵌套定义。
函数的嵌套调用的好处:调用节省代码、
函数嵌套调用:函数my_max_pro嵌套了函数my_max,并且调用了my_max的方法。
def my_max(x,y): res = x if x>y else y return res def my_max_pro(a,b,c,d): res1 = my_max(a,b) res2 = my_max(res1,c) res3 = my_max(res2,d) return res3 print(my_max_pro(1,56,2,68))
函数嵌套定义:就是在函数里面在定义一个函数。
嵌套函数的找值顺序是:局部> 全局> 内置
x = 4
def f1(): x = 1 print("f1",x) def f2(): x = 2 print("f2",x) def f3(): x = 3 print("f3",x) f3() #和f2同理 如果f3的x没有值,就顺序去f2里找,f2没有就去f1找,f1还没有,就去全局找。 f2() # 执行局部f2,局部的函数在全局是执行不了的 f1() #全局找f1并执行,但不会执行f2和f3
用主函数来调用函数。
#写主函数,用于调用函数功能 #Python为每个文件内置了一个__name__ if __name__ == '__main__': # main tab 就出来了 #文件此时的用途是,被当做脚本用 pass
函数是第一类对象的概念:
函数就相当于一个变量。函数可以被赋值。
def foo(): print('函数foo') print(foo) #打印函数foo的内存地址 ######函数可以被赋值 f=foo #把函数赋予一个变量名 print(f) #打印变量名,结果也依旧是函数foo的内存地址 f() #调用函数foo,打印函数foo里面的结果
函数可以被当做参数被传递。
def foo(): print('函数foo') ##########把函数当成参数传递 def bar(func): print(func) #打印函数的内存地址,也就是函数foo的内存地址 func() #执行foo函数,打印函数foo的结果 bar(foo)
函数可以被当做是返回值传递。
def foo(): print('函数foo') #################### 把函数当成返回值 def bar(func): #bar的参数是func,func是foo print(func) #打印函数foo的内存地址 return func #返回函数foo的值 f=bar(foo) #将foo的返回值赋予一个变量f print(f) #f是函数foo的内存地址 f() #执行foo函数
函数可以被当做是容器类型的元素传递。
def create(): print('function ---->create') def add(): print('=============>function add') def search(): print('=============>function search') def delete(): print('=============>function delete') def change(): print('=============>function change') def tell_msg(): msg=''' search:查询 add:添加 delete:删除 change:修改 create:新建 ''' print(msg) cmd_dic={ 'search':search, #value是函数的内存地址 'add':add, 'delete':delete, 'change':change, 'create':create } while True: tell_msg() choice=input('please input your choice: ').strip() print(choice) #打印选择的是cmd_dic的字典的key # print(cmd_dic[choice]) #通过key可以找到他对应的value,也就可以拿到他对应的函数的内存地址,也就可以执行那个函数。 cmd_dic[choice]() #加()就可以调用运行。
闭包函数:
闭包函数使其外部函数变量无法干预或改变函数内部的变量值。
闭包:首先必须是内部定义的函数,该函数包含对外部作用域而不是全局作用域名字的引用
x=1 def f1(): def f2(): print(x) return f2 ##这就不是闭包,因为内部函数f2引用的x是全局的x。
闭包的样例:
x=1 def f1(x): x=1000 def f2(): print(x) return f2 f = f1() f() ### 这时的f2()的x是引用的闭包里f1()的x的值。
闭包的使用:
from urllib.request import urlopen def get(url): return urlopen(url).read() def f1(url): def f2(): print(urlopen(url).read()) return f2 # print(get('http://www.baidu.com')) f=f1('http://www.python.org') f()
-------------- END -------------