zoukankan      html  css  js  c++  java
  • 闭包 装饰器

    闭包

    我们先用一个例子来理解闭包:

    def fun1():
        a, b, c = 1, 2, 3
    
        def fun2():
            x = 100
            print "outer var a is ", a
            print "inner var x is", x
    
        return fun2
    
    f = fun1()
    f()
    

    上述代码,运行f()输出如下:

        outer var a is 1
        inner var x is 100
    

    虽然f 是 fun1的返回,按理说就是fun2。 但实际上又不是fun2. 它是fun2和变量a的一个集合。我们这里称其为闭包。 闭包的定义如下:

    嵌套定义在非全局作用域中的函数,当它的外部函数被调用就会生成一个闭包,闭包中包含了这个子函数本身的代码与其依赖的外部变量的引用
    

    装饰器就是通过闭包来实现的。

    普通装饰器

    def outter(function):
    
        def wrapper():
            print "do something before call func"
            result = function()
            print "do something after call func"
            return result
    
        return wrapper
    
    
    def hello():
        print "hello"
    
    
    hello = outter(hello)
    
    hello()
    

    这里的wrapper调用了其外部的function。在outter(hello) 返回后,返回的其实不是wrapper,而是wrapper和hello的一个集合。 这就是python装饰器的原理。不过python加了一些语法糖,所以真正写装饰圈的时候语法如下:

    @outter
    def hello():
        ...
    

    它相当于 hello = outter(hello)

    带参数的装饰器

    没有参数的装饰器如下

    @outter
    def hello():
        ...
    

    有参数的就应该是

    @outter(*args, **kwargs)
    def hello():
        ...
    

    它相当于 hello = outter(*args, **kwargs)(hello) 也就是说,我们让outter再返回一个装饰器即可,比如:

    def outter(*args, **kwargs):
    
        def outter1(func):
    
            print "*args or decorator ", args
            print "**kwargs of decorator ", kwargs
    
    
            def wrapper():
                print "do something before call func"
                result = func()
                print "do something after call func"
                return result
    
            return wrapper
        return outter1
    
    
    @outter('arg1','arg2','arg3', kw1='kw1',kw2='kw2')
    def hello():
        print "hello"
    
    
    hello()
    

    运行如下:

    *args or decorator  ('arg1', 'arg2', 'arg3')
    **kwargs of decorator  {'kw1': 'kw1', 'kw2': 'kw2'}
    do something before call func
    hello
    do something after call func
  • 相关阅读:
    unityshader(属性)
    unity_实用小技巧(相机跟随两个主角移动)
    unity_实用小技巧(空指针错误)
    unity_实用小技巧(避免游戏对象被销毁时声音消失)
    php把网络图片转Base64编码。(php将图片链接直接转化为base64编码)
    TP5.0 where数组高级查询
    使用Guzzle执行HTTP请求
    JWT实战:使用axios+PHP实现登录认证
    有关JWT(Json Web Token)的那些事
    thinkphp5一键清除缓存
  • 原文地址:https://www.cnblogs.com/kramer/p/6763424.html
Copyright © 2011-2022 走看看