函数的名称空间及嵌套和闭包

函数的名称空间及嵌套和闭包

返回首页

函数的名称空间:名称空间分为三种,分别是内置名称空间、全局名称空间以及局部名称空间。

  内置名称空间:就是内置函数方法,解释器一启动就加载在里面的方法。

  全局名称空间:在组代码中,没有缩进的名称变量或函数方法,就是全局名称空间。

         被定义好的全局名称空间可以在代码中的任何地方被使用。

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 -------------

原文地址:https://www.cnblogs.com/george92/p/13539854.html