zoukankan      html  css  js  c++  java
  • 【摘】人生苦短,每日python

    python和它的装饰器

    即使你没听过装饰器,你也一定知道@staticmethod

    作为函数的装饰器,你可以这样写

    def mydecorator(function):
    
        def wrapped(*args, **kwargs):
    
            # 在调用原始函数之前, 做点什么
            result = function(*args, **kwargs)
            # 在函数调用之后, 做点什么
            # 并返回结果
            return result
        # 返回warpper作为装饰函数
        return wrapped
    

    作为一个例子,我写了个非常随意的

    def print_hello(function):
    
        def hello(*args, **kwargs):
    
            print('hello start')
            result = function(*args, **kwargs)
            print('hello end')
            return 'hello %s' % result
        return hello
    
    @print_hello
    def print_world():
    
        print('world print')
        return 'world result'
    
    if __name__ == '__main__':
    
        print(print_world())
    

    它的结果是

    hello start
    world print
    hello end
    hello world result
    

    作为类的装饰器,你可以这样写

    class DecoratorAsClass(object):
        
        def __init__(self, function):
            
            self.funciton = function
            
        def __call__(self, *args, **kwargs):
            
            # 在调用原始函数之前, 做点什么
            result = self.funciton(*args, **kwargs)
            # 在调用函数之后, 做点什么
            # 并返回结果
            return result
    

    作为一个例子,我依旧写了一个很随意的

    class PrintWrappedClass(object):
    
        def __init__(self, function):
    
            self.function = function
    
        def __call__(self, *args, **kwargs):
    
            print('wrapped start')
            result = self.function(*args, **kwargs)
            print('wrapped end')
            return result
    
    @PrintWrappedClass
    class PrintWorld (object):
    
        def print_world(self):
    
            print('world print')
            return 'world result'
    
        def print_kitty(self):
    
            print('kitty print')
            return 'kitty result'
    
    if __name__ == '__main__':
        print(PrintWorld().print_world())
        print('___')
        print(PrintWorld().print_kitty())
    

    它的结果是

    wrapped start
    wrapped end
    world print
    world result
    ___
    wrapped start
    wrapped end
    kitty print
    kitty result
    

    当然,装饰器也可以传参

    def repeat(number=3):
    
        def actual_decorator(function):
    
            def wrapper(*args, **kwargs):
    
                result = None
                for _ in range(number):
                    result = function(*args, **kwargs)
                return result
            return wrapper
        return actual_decorator
    
    @repeat(2)
    def print_kitty():
    
        print('kitty print')
        return 'kitty result'
    
    
    if __name__ == '__main__':
    
        print(print_kitty())
    

    它的结果是

    kitty print
    kitty print
    kitty result
    

    然后我想了想,为什么不像函数装饰器的模板那么写呢?

    于是,我就随意地写了个错误的例子

    def error_repeat(function, number=3):
    
        def wrapper(*args, **kwargs):
    
            result = None
            for _ in range(number):
                result = function(*args, **kwargs)
            return result
        return wrapper
    
    @error_repeat
    def print_world():
    
        print('world print')
        return 'world result'
    

    它的结果是

    world print
    world print
    world print
    world result
    

    很完美,但是当我想传参数进去的时候,犯难了

    呃,就姑且将这个错误的示例当做个笑话看看吧

    保存内省的装饰器

    from functools import wraps
    
    def preserving_decorator(function):
    
        @wraps(function)
        def wrapped(*args, **kwargs):
    
            # 包装函数内部文档
            return function(*args, **kwargs)
        return wrapped
    

    说实话,我没看懂这段

    所以摘录下书中的原话

    使用装饰器的常见错误是在使用装饰器时不保存函数元数据(主要是文档字符串和原始函数名)。
    前面所有示例都存在这个问题。
    装饰器组合创建了一个新函数,并返回一个新对象,但却完全没有考虑原始函数的标识。这将使得调试这样装饰过的函数更加困难,也会破坏可能用到的大多数自动生成文档的工具,因为无法访问原始的文档字符串和函数签名。

    摘自 《Python高级编程》

  • 相关阅读:
    多种方式实现数组的扁平化处理
    利用node中的内置模块fs实现对简单文件的读取 拷贝 创建等功能
    浅谈es5和es6中的继承
    js之冒泡排序与快速排序
    IE5,IE6,IE7,IE8的css兼容性列表[转自MSDN]
    css3 动画
    各种浏览器css hack
    解决li在ie,firefox中行高不一致问题
    Css:背景色透明,内容不透明之终极方法!兼容所有浏览器
    png-24在ie6中的几种透明方法
  • 原文地址:https://www.cnblogs.com/featherw/p/10311094.html
Copyright © 2011-2022 走看看