zoukankan      html  css  js  c++  java
  • 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')
  • 相关阅读:
    107. Binary Tree Level Order Traversal II
    103. Binary Tree Zigzag Level Order Traversal
    102. Binary Tree Level Order Traversal
    690. Employee Importance
    1723. Find Minimum Time to Finish All Jobs
    LeetCode 329 矩阵中最长增长路径
    7.2 物理内存管理
    LeetCode 面试题 特定深度节点链表
    LeetCode 100 相同的树
    npm安装包命令详解,dependencies与devDependencies实际区别
  • 原文地址:https://www.cnblogs.com/hexiaorui123/p/9995475.html
Copyright © 2011-2022 走看看