闭包函数

闭包函数

1.函数对象

定义:把函数的内存地址当做一种变量值一样去使用------函数对象

函数对象的引用一共有4种,分别是:

1.直接将函数名赋值给一个变量:

def func1():
    print('from func1')
func2=func1
func2()

此时我的func2这个变量的值便是func1这个函数的内存地址,
我在func2后面加个括号就等于对func1加上了括号,只是此
时调用的方式不一致,这种方法在后面的装饰器部分也又用到。
这个代码的运行结果是:
from func1

2.可以当做参数传给另外的函数:

def func1():
    print('from func1')

def bar(xxx):
    # print(xxx)
    xxx()

bar(func1)

如上述代码,在调用bar函数时,我们传入了另外一个函数func1,
在bar函数中,我们既输出了传入函数对象既func1的内存地址,
也对存入的函数对象进行了调用,最终结果为:
<function func1 at 0x000001DB32915598> from func1

3.可以当做一个函数的返回值:

def func1():
    print('from func')

def bar():
    return func1

f=bar()
f()

 4.可以当作容器类型的元素:在选择功能的时候可以使用这种方式,技能方便修改,也能减少代码量。

ef register():
    print('注册')

def login():
    print('登陆')

def shopping():
    print('购物')

def pay():
    print('支付')

func_dic={
    '1':register,
    '2':login,
    '3':shopping,
    '4':pay
}

while True:
    print("""
    0 退出
    1 注册
    2 登陆
    3 购物
    4 支付
    """)
    choice=input('>>>: ').strip()
    if choice == '0':break
    if choice in func_dic:
        func_dic[choice]()
    else:
        print('输入错误的指令')

2.函数的嵌套

函数的嵌套分为两种:函数的嵌套调用  和    函数的嵌套定义

1.函数的嵌套调用:在函数内调用了其他函数

def max2(x,y):
    if x > y:
        return x
    else:
        return y


def max4(a,b,c,d):
    res1=max2(a,b)
    res2=max2(res1,c)
    res3=max2(res2,d)
    return res3

上述代码,使用了函数的嵌套调用的思想,当我们需要解决一
个比较4个数大小的需求时,我们可以将它分成很多的小问题,
在此场景中,我们定义了一个比较2个数大小的函数,在需要完成
比较4个数的大小时,便可以在函数中调用max2函数以解决这个问题。

2.函数的嵌套定义:在函数内定义了其他函数

from math import pi

def circle(radius,mode=0):
    def perimiter(radius):
        return 2 * pi * radius

    def area(radius):
        return pi * (radius ** 2)

    if mode == 0:
        return perimiter(radius)
    elif mode == 1:
        return area(radius)

我们将求圆的周长与圆的面积的函数定义在了一个大
函数circle中,只需要选择在circle函数中传入的参数
我们就可以选择我们需要调用的函数。

3.名称空间

定义:存放名字与内存地址绑定关系的地方

名称空间分为三类:

1.内置名称空间:存储解释器自带的一些名称与值的对应关系

    (python解释器启动时创建 所有代码全部执行完毕 关闭解释器时 销毁)

2.全局名称空间:只要你的名字的定义是顶着最左边写的就在全局空间(如果if顶级,那么if中的变 量名也属于全局名称空间)(执行py文件创建全局名称空间 关闭解释器时 销毁)

3.局部名称空间:只要是函数内的名称就是局部的

     (调用函数时创建 函数执行完毕就销毁)

    名称空间的加载顺序:内置的 ->   全局的 ->   局部的

    名称的查找顺序:从当前位置往外一层一层的查找

         如果当前处于局部名称空间:当前位置所在的局部----->全局------->内置

         如果当前处于全局名称空间:全局------->内置

4.作用域

定义:域指的是区域,范围的的意思.。作用域就是名称空间的范围

作用域的分类:1.全局作用域  2.局部作用域

1.全局作用域:包含内置与全局名称空间的名字   特点:全局存活,全局有效

2.局部作用域:包含局部名称空间的名字    特点:临时存活,局部有效

特别注意:作用域的关系在函数的定义阶段就已经存在固定死了,与调用位置无关!!!

def f1():
    print(xxx)
xxx=111
def f2():
    xxx=222
    f1()
f2()

调用函数f2时,这个代码的运行结果为111,因为在函数定义时,
f1中有一个print(xxx),但是在f1函数这个局部作用域中并没
有xxx这个变量,所以它会向外部(全局作用域)中区寻找,返现
xxx
=111,所以在调用f2时,输出结果会是111,因为在函数定义的时候已经固定死了

5.global 和 nonlocal 关键字

global:在局部变量声明变量是全局变量,声明后再局部变量中可以修改全局变量

def f1():
    print(xxx)
xxx=111
def f2():
    glocal xxx
    xxx=222
    f1()
f2()

此时在f2中声明xxx为全局变量后,就可以对xxx进行修改,此时xxx=222就是全局变量,因此输出为222

 

nonlocal:在局部变量中声明变量是外层函数变量(永远都不会找到全局变量中)

6.闭包函数

定义:闭函数:该函数一定是定义在函数内的函数

           包函数:该内部函数包含对外层函数作用域名字的引用

闭包函数模板:

def outter():
    x=10
    def inner():
        print(x)
    return inner

闭包函数也可以为函数体传值:

def outter(x):
    def inner():
        print(x)
    return inner

 

posted on 2018-11-30 21:25  黑粥  阅读(155)  评论(0编辑  收藏  举报

导航