zoukankan      html  css  js  c++  java
  • [Python]工厂函数

    python有一个很有意思的地方,就是def函数可以嵌套在另一个def函数之中,调用外层函数时,运行到的内层def语句仅仅是完成对内层函数的定义,而不会去调用内层函数,除非在嵌套函数之后又显式的对其进行调用;

    例如:

    x = 99
    def f1():
        x = 88
        def f2():
            print(x)
        f2()
    f1()

    最后的输出结果为:

    88

    可以看出,f1中的嵌套变量x覆盖了全局变量x=99,然后f2中的本地变量按照引用规则,就引用了x=88;

    另一个例子:

    x = 99
    def f1():
        x = 88
        def f2():
            print(x)
        f2()
    f1()
    print(x)

    最后的输出结果为:

    99

    下面我们来说说嵌套作用域的一个特殊之处:

    本地作用域在函数结束后就立即失效,而嵌套作用域在嵌套的函数返回后却仍然有效;

    闭包:一个能记住嵌套作用域变量值的函数,尽管作用域已经不存在;

    这里有一个闭包的应用——工厂函数,工厂函数定义了一个外部的函数,这个函数简单的生成并返回一个内嵌的函数,仅仅是返回却不调用,因此通过调用这个工厂函数,可以得到内嵌函数的一个引用,内嵌函数就是通过调用工厂函数时,运行内部的def语句而创建的。

    def maker(n):  
        k = 8
        def action(x):   
            return x ** n + k
        return action
    
    f = maker(2)
    print(f(2))

    最后输出结果为:

    8

    这里我们可以看出,内嵌的函数action记住了嵌套作用域内得两个嵌套变量,一个是变量k,一个是参数n,即使后面maker返回并退出。我们通过调用外部的函数maker,得到内嵌的函数action的引用。

    这种函数嵌套的方法在后面要介绍的装饰器中会经常用到。

    这种嵌套作用域引用,就是python的函数能够保留状态信息的主要方法了。

    这里介绍另外一个关键字nonlocal:


    本地函数通过global声明对全局变量进行引用修改,那么对应的,内嵌函数内部想对嵌套作用域中的变量进行修改,就要使用nonlocal进行声明。

    例如:

    def test(num):
        in_num = num
        def nested(label):
            nonlocal in_num
            in_num += 1
            print(label, in_num)
        return nested
    F = test(3)
    F('a')
    F('b')
    F('c')

    最后的输出结果为:

    a 4
    b 5
    c 6

    这里我们可以看到几个点,我们在nested函数中通过nonlocal关键字引用了内嵌作用域中的变量in_num,那么我们就可以在nested函数中修改他,即使test函数已经退出调用,这个“记忆”依然有效。

    最后一个例子:

    def test(num):
        in_num = num
        def nested(label):
            nonlocal in_num
            in_num += 1
            print(label, in_num)
        return nested
    F = test(3)
    F('a')
    F('b')
    F('c')
    
    G = test(100)
    G('mm')

    最后的输出结果为:

    a 4
    b 5
    c 6
    mm 101

    多次调用工厂函数返回的不同内嵌函数副本F和G,彼此间的内嵌变量in_num是彼此独立隔离的。

  • 相关阅读:
    MSSQL锁定1.Isolation level (myBased)
    等待状态CXPACKET分析
    拒绝了对对象 'sp_sdidebug'(数据库 'master',所有者 'dbo')的 EXECUTE 权限
    Oracle CBO 统计信息的收集与执行计划的选择
    Oracle 11gR1 on Win7
    读书笔记 <<你的知识需要管理>>
    ORA01555 总结
    Buffer Cache Management
    如何选择合适的索引
    书评 <SQL Server 2005 Performance Tuning性能调校> 竟然能够如此的不用心........
  • 原文地址:https://www.cnblogs.com/LeeCookies/p/15395144.html
Copyright © 2011-2022 走看看