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
  • 相关阅读:
    window.clipboardData(转载)
    动态添加样式(转载)
    IE6 IE7 FF的CSS Hack总结(转载)
    [轉貼] linux解壓 tar 命令
    [轉]用 snprintf / asprintf 取代不安全的 sprintf
    寫一個函數計算當參數為 n(n很大) 時的值 12+34+56+7……+n
    [轉]vi 與 vim 的指令整理
    MySQL和php採用UTF8的方法
    [轉]printf 引數說明
    [C] warning: ISO C90 forbids mixed declarations and code
  • 原文地址:https://www.cnblogs.com/kramer/p/6763424.html
Copyright © 2011-2022 走看看