python开发函数进阶:命名空间,作用域,函数的本质,闭包,作用域方法(globales)

一,命名空间

#局部命名空间
#全局命名空间
#内置命名空间

#三者的顺序
#加载顺序       内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

取值

*在局部调用:局部命名空间》全局命名空间》内置命名空间

1 #!/usr/bin/env python
2 #_*_coding:utf-8_*_
3 
4 max = 1
5 def f():
6     print(max)  #局部调用max会找全局max=1,如果没有就会打印内置max
7 f()

*在全局调用:全局命名空间》内置命名空间

#!/usr/bin/env python
#_*_coding:utf-8_*_

x = 1
def f(x):
    print(x)
f(10)
print(x)

 

复制代码
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 #全局命名空间
 5 a = 5
 6 b = 8
 7 #局部命名空间(函数)
 8 def my_max():
 9     c = a if a > b else b
10     return c
11 m = my_max()
12 print(m)
复制代码

 

二,作用域

#命名空间+作用域是分不开的
#两种
#全局作用域:全局命名空间、内置命名空间
#局部作用域:局部命名空间

#站在全局看:
#使用名字:
#如果全局有:用全局的
#如果全局没有:用内置的

#为什么要有作用域的概念:
#为了函数内的变量不会影响到全局

复制代码
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 def max(a,b):
 5     a = 10  #局部
 6     b = 20
 7 a = 2    #全局
 8 b = 3    #
 9 max(30,50)
10 print(a,b)
复制代码

 总结:

#小范围的可以用大范围的
#但是大范围的不能用小范围的
#在小范围内,如果要用一个变量,是当前这个小范围有的,就用自己的
#如果在小范围内没有,就用上一级的,上一级没有就用上上一级的,以此类推。
#如果都没有,报错

三,作用域链,小范围的可以用大范围的

复制代码
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 x = 1
 5 def heihei():
 6     def inner1():
 7         def inner2():
 8             print(x)
 9         inner2()
10     inner1()
11 heihei()
复制代码

 

四,函数的嵌套

#为了保护内部函数,确定内部函数只能在外部函数中被调用

复制代码
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 #函数嵌套
 5 def animal():
 6     def tiger():
 7         print('bark')
 8     print('eat')
 9     tiger()
10 animal()
11 
12 #函数嵌套使用
13 def f1():
14     print(a)  #无法获取f2的a的值,注意执行顺序
15     print('f1')
16 def f2():
17     a = 10
18     f1()
19 f2()
复制代码

 

五,函数名的本质就是内存地址

复制代码
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 def func():
 5     print('func')
 6 print(func)   #函数func内存地址
 7 f = func    #就是函数的内存地址
 8 print(f)   #函数func内存地址
 9 f()  #执行代码
10 #############
11 l = [f]     #还是函数内存地址
12 print(l)
13 l[0] == f  #用索引取值
14 l[0]()
15 
16 #可以用作函数的参数
17 def func():
18     print('func')
19 def func2(f):
20     print(f)   #func的内存地址
21     f()        #执行func函数
22     print('func2')
23 func2(func)
24 
25 #可以作为函数的返回值
26 def func():
27     print('func')
28 def func2(f):   #1 接收func函数的内存地址
29     print('func2')
30     return f    #2 返回给fu函数func函数的内存地址
31 fu = func2(func)
32 fu()    #3  执行函数func
33 
34 #如果我想在全局使用内部的函数
复制代码

 

六,闭包

#1.闭 :内部的函数
#2.包 :包含了对外部函数作用域中变量的引用

复制代码
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 #闭包函数:内部函数,包含了对外部作用域中变量的引用
 5 def hei():
 6     x = 20
 7     def inner():
 8         '''
 9         闭包函数
10         '''
11         print(x)
12 
13 #闭包的常用形式
14 def hei():
15     x = 20
16     def inner():
17         print(x)  #局部的
18     return inner
19 i = hei()
20 i()  #全局
21 
22 
23 #闭包的例子,爬网页,函数执行完就会消失,但是在调用的时候又会打开,闭包解决了这个问题
24 from urllib.request import urlopen
25 # def index():
26 #     url = "http://www.cnblogs.com/Eva-J/articles/7125925.html"
27 #     return urlopen(url).read()
28 # index()
29 
30 def index():
31     url = "http://www.cnblogs.com/Eva-J/articles/7125925.html"
32     def inner():
33         return urlopen(url).read()
34     print(inner.__closure__)
35     return inner
36 # u = "http://www.cnblogs.com/Eva-J/articles/7125925.html"
37 get = index()
38 print(get())
复制代码

 

7,作用域方法

#locals,globals方法,只有globals方法,作用是将局部作用域内的变量可以变成全局作用域的变量

复制代码
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 a = 20
 5 b = 50
 6 def haha():
 7     x = 1
 8     y = 2
 9     print(globals())  #全局作用域中的名字a b 方法haha
10     print(locals())   #局部作用域中的名字x y
11 haha()
12 print(globals())  #全局作用域中的名字
13 print(locals())   #全局的局部还是全局
复制代码

nonlocal
# 1.外部必须有这个变量
# 2.在内部函数声明nonlocal变量之前不能再出现同名变量
# 3.内部修改这个变量如果想在外部有这个变量的第一层函数中生效

复制代码
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 def f():
 5     a = 3
 6     def f1():
 7         a = 1
 8         def f2():
 9             nonlocal a   #可以将上一层的变量更改赋值
10             a = 2
11         f2()
12         print('a in f1 : ', a)    #此时a是内部函数的a
13     f1()
14     print('a in f : ',a)    #此时a是局部函数的a
15 f()
16 #a in f1 :  2
17 #a in f :  3
复制代码

 

posted @   liqianlong  阅读(364)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示