• 函数之命名空间、作用域、闭包、装饰器四剑客。


    # 1.三元运算
    # name=1 if 1>2 else 3
    # print(name)
    
    
    # 2.命名空间
    # 全局命名空间:创建的存储“变量名与值的关系”的空间叫做全局命名空间
    # 局部命名空间:在【函数】的运行中开辟的临时的空间叫做局部命名空间
    
    # 内置命名空间:内置命名空间中存放了python解释器为我们提供的名字:
    # input,print,str,list,tuple... 它们都是我们熟悉的,拿过来就可以用的方法。
    
    # 2.1命名空间的加载顺序:
        # python解释器先启动,因而首先加载的是:内置名称空间
        #执行test.py文件,然后以文件为基础,加载全局名称空间
        #在执行文件的过程中如果调用函数,则临时产生局部名称空间
    
    
    
    # 3.1三种命名空间之间的使用顺序:
    # 3.1.全局的不能使用局部的
    # 3.2.局部的可以使用全局的
    
    
    # 4.作用域:作用的范围(作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关)
    # 4.1.首先作用域与命名空间是密不可分的
    # 4.2 作用域分为两种:
        # 1.全局作用域:全局的命名空间与内置命名空间都属于全局范围,在整个文件的任意位置都能被引用,全局有效
        # 2.局部作用域:局部命名空间,只能在局部范围内生效
    # 4.3以全局的角度分析:使用名称的时候如果全局有则使用全局的,没有使用内置的,但全局的不能使用局部的
    # 4.4 作用域的作用:为函数内的局部变量不受全局的影响
    # 4.5查看作用域:globals(),locals()
        # LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
        # locals 是函数内的名字空间,包括局部变量和形参
        # enclosing 外部嵌套函数的名字空间(闭包中常见)
        # globals 全局变量,函数定义所在模块的名字空间
        # builtins 内置模块的名字空间
    
    
    
    
    #5.闭包函数:
            #内部函数 包含对外部作用域  而非全局作用域的引用
    def outer():
        name="alex"
         def inner():
            print(name)  #内部嵌套函数 包含了多外部函数outer的变量的引用  不是全局变量!
         return inner
    
    def counter():
        n = 0
        def incr():
            nonlocal n  # nonlocal关键字用来在函数或其他作用域中使用外层(非全局)变量。
            x = n
           n += 1
           return x
        return incr
     c = counter()
     print(c())  #每次调用的时候counter 都会加一n  因为在内部inrc函数中声明n引用counter的n
     print(c())
     print(c())
    
     print("q", c.__closure__[0].cell_contents)  # 查看闭包的元素
    # 5.2闭包的意义与应用:
    # 闭包的意义:
        # 返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,
        # 这使得,该函数无论在何处调用,
        # 优先使用自己外层包裹的作用域
    from urllib.request import urlopen
    def index(url):
        def get():
            return urlopen(url).read()
        return get
    
    baidu = index('http://www.baidu.com')  #调用内部get之前就把url确定
    # print(baidu().decode('utf-8'))  #执行 打开index 下刚定义的局部变量url
    
    6.0 装饰器
    装饰器就是闭包函数的一种应用场景
    为啥要用装饰器:开放封闭原则:对修改封闭,对扩展开放
    6.1 何为装饰器:
    装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
        强调装饰器的原则:
             1 不修改被装饰对象的源代码
              2 不修改被装饰对象的调用方式
        装饰器的目标:
             在遵循1和2的前提下,为被装饰对象添加上新功能
     1 status_flag=False
     2 
     3 
     4 def login(func):   #把被装饰的函数当做参数传进来
     5 
     6     def inner(*args,**kwargs):
     7         global status_flag
     8         _name = "alex"  #进行验证
     9         _passwd="123"
    10         if status_flag == False:
    11             user = input("user>:")
    12             pwd = input("pwd>:")
    13             if user==_name and pwd == _passwd:
    14                 status_flag=True
    15                 print("ok") #通过就执行此函数,并且把内部的函数 的内存地址返回给login
    16                 func(*args,**kwargs)
    17             else:
    18                 print("erro!")
    19         elif  status_flag:
    20             func(*args,**kwargs)
    21     return inner   #返回嵌套函数的内存地址给外层  外层被调用的时候才执行
    22 @login  #henan[返回新的河南的内存地址,只有调用才执行]=login(hanne(传进去的老的河南))
    23 def henan(name):
    24     print(name)
    25     print("欢迎进入河南专区".center(50, "*"))
    26 @login
    27 def hangzhou():   #杭州默认不加参数 调用的时候也不可以加,如果加参数,这样调用的时候才加参数
    28     print("欢迎进入杭州专区".center(50, "*"))
    29 
    30 
    31 print("装饰器进阶版".center(100, "*"))
    32 
    33 #***************************************************************************************
    34 
    35 
    36 
    37 status_flag = False
    38 
    39 def login(auth_type):  # 接收装饰器函数的参数
    40 
    41     def outer(func):  # 把被装饰的函数当做参数传进来
    42 
    43         def inner(*args, **kwargs):
    44             global status_flag
    45             _name = "alex"  # 进行验证
    46             _passwd = "123"
    47             if status_flag == False:
    48                 user = input("user>:")
    49                 pwd = input("pwd>:")
    50                 if user == _name and pwd == _passwd:
    51                     status_flag = True
    52                     print("ok")  # 通过就执行此函数,并且把内部的函数 的内存地址返回给login
    53                     func(*args, **kwargs)
    54                 else:
    55                     print("erro!")
    56             elif status_flag:
    57                 func(*args, **kwargs)
    58 
    59         return inner  # 返回嵌套函数的内存地址给外层  外层被调用的时候才执行
    60 
    61     return outer
    62 
    63 
    64 # 在调用login的时候自动传入参数。
    65 
    66 @login('aa')
    67 def henan(name):
    68     print(name)
    69     print("欢迎进入河南专区".center(50, "*"))
    70 
    71 
    72 @login("wx")  # login("wx")(henan) 没执行之前其实已经做了这个转变
    73 def hangzhou():
    74     print("欢迎进入杭州专区".center(50, "*"))
    75 
    76 
    77 # hangzhou()   #函数本身没有加参数,则调用也不能加
    78 henan("sp")
    装饰器的应用

      

     

  • 相关阅读:
    【WPF】代码触发Button点击事件
    [WPF]静态资源(StaticResource)和动态资源(DynamicResource)
    stm32f103_arduino
    解除github下载的文件的锁定
    c# wpf binding
    mysql 使用可能遇到的问题
    c# progressbar
    STM32串口IAP(YModem) (转载)
    VS2017、VS2019安装包制作(转)
    八、ES集群搭建
  • 原文地址:https://www.cnblogs.com/zjcode/p/8596944.html
Copyright © 2020-2023  润新知