• Python-函数进阶


    一、名称空间:存放变量名与对应值绑定关系的地方。

    分为三种:locals(),是函数内的名称空间,包含局部变量与形参;globals():全局变量,函数定义所在模块的名字空间;builtins():内置模块的名字空间。

    level = 'l0'
    n = 22
    def func():
        level = 'l1'
        n = 33
        print(locals())
    
        def outer():
            n = 44
            level = 'l2'
            print(locals(),n)
    
            def inner():
                level = 'l3'
                print(locals(),n)
            inner()
        outer()
    func()
    
    #打印 func()/outer()/inner()
    
    {'level': 'l1', 'n': 33}
    {'level': 'l2', 'n': 44} 44
    {'level': 'l3', 'n': 44} 44

    #名称空间查找顺序:局部名称空间--->全局名称空间--->内置名称空间

    不同变量的作用域不同是由这个变量所在的命名空间决定的。

    作用域即范围:全局范围:全局存活,全局有效;局部范围:临时存活,局部有效。

    #1、作用域即范围
            - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效
          - 局部范围(局部名称空间属于该范围):临时存活,局部有效
    #2、作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下
    x=1
    def f1():
        def f2():
            print(x)
        return f2
    x=100
    def f3(func):
        x=2
        func()
    x=10000
    f3(f1())
    
    #3、查看作用域:globals(),locals()
    
    
    LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
    locals 是函数内的名字空间,包括局部变量和形参
    enclosing 外部嵌套函数的名字空间(闭包中常见)
    globals 全局变量,函数定义所在模块的名字空间
    builtins 内置模块的名字空间

    二、闭包

    定义:内部函数包含对外部作用域,而非全局作用域的引用。之前我们都是通过参数将值传给函数,闭包给我们提供了一种新的方式。

     outer():
        name='alex'
    
        def inner():
            print("在inner里面打印外层函数的变量", name)
        return inner
    
    f = outer()
    f()

     闭包的意义:

    返回的函数对象,不仅仅是一个函数对象,在该函数外层还包裹着一层作用域,这使得函数无论在何处调用,都优先使用自己外层包裹的作用域。应用:延迟计算。

    def counter():
        n = 0
    
        def incr():
            nonlocal n
            x = n
            n += 1
            return x
    
        return incr
    
    
    c = counter()
    print(c())
    print(c())
    print(c())
    print(c.__closure__[0].cell_contents)  # 查看闭包的元
    

     三、装饰器

    定义:装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。

    强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方法。

    装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能

    开放封闭原则:对修改封闭,对拓展开放

    装饰器就是闭包的一种应用场景

    装饰器的使用:

    1、无参数的使用

    import time
    def timmer(func):
        def wrapper(*args,**kwargs):
            start_time=time.time()
            res=func(*args,**kwargs)
            stop_time=time.time()
            print('run time is %s' %(stop_time-start_time))
            return res
        return wrapper
    
    @timmer
    def foo():
        time.sleep(3)
        print('from foo')
    foo()

    2、有参数的使用

    def auth(driver='file'):
        def auth2(func):
            def wrapper(*args,**kwargs):
                name=input("user: ")
                pwd=input("pwd: ")
    
                if driver == 'file':
                    if name == 'egon' and pwd == '123':
                        print('login successful')
                        res=func(*args,**kwargs)
                        return res
                elif driver == 'ldap':
                    print('ldap')
            return wrapper
        return auth2
    
    @auth(driver='file')
    def foo(name):
        print(name)
    
    foo('egon')
  • 相关阅读:
    LinqToSQL4
    java 连接数据库操作
    javadoc生成文档报错 java.lang.IllegalArgumentException
    maven下载依赖jar包,Could not transfer artifact xxxxx
    关于meaven导入依赖出现Failed to read artifact descriptor for ***包
    mybatis-plus项目自动生成代码
    Spring boot 出现 "org.springframework.beans.factory.UnsatisfiedDependencyException" 错误
    vs 调试显示用户关闭隐式函数计算
    vue api排放顺序及属性,用于理解vue
    vue 拦截器
  • 原文地址:https://www.cnblogs.com/hexiaorui123/p/9995475.html
Copyright © 2020-2023  润新知