Python装饰器

在不影响函数的情况下,提供更多的功能。

本质:python函数或类。  让其他函数或类在不需要做任何代码修改的前提下增加额外功能,返回值也是函数或类对象。

插入日志、性能测试、事务处理、缓存、权限校验等场景,装饰器是解决这类问题的绝佳设计。

我们可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用。

def foo():
    print("foo")
    logging.info("foo is running")    #新的需求,希望可以记录下函数的执行日志

def bar(func):      #Python 中的函数可以像普通变量一样当做参数传递给另外一个函数 func() bar(foo)

 减少重复代码:

def use_logging(func):
    logging.warn("%s is running" % func.__name__)
    func()

def foo():
    print('i am foo')

use_logging(foo)

 简单装饰器:    面向切面的编程

def use_logging(func):

    def wrapper():
        logging.warn("%s is running" % func.__name__)
        return func()   # 把 foo 当做参数传递进来时,执行func()就相当于执行foo()
    return wrapper

def foo():
    print('i am foo')

foo = use_logging(foo)  # 因为装饰器 use_logging(foo) 返回的时函数对象 wrapper,这条语句相当于  foo = wrapper
foo()                   # 执行foo()就相当于执行 wrapper()

 @ 语法糖  放在函数开始定义的地方,这样就可以省略最后一步再次赋值的操作。

def use_logging(func):

    def wrapper():
        logging.warn("%s is running" % func.__name__)
        return func()
    return wrapper

@use_logging
def foo():
    print("i am foo")

foo()

 

 提高了程序的可重复利用性,并增加了程序的可读性。(函数还是原来的函数,装饰器只不过是为它提供了更多的东西)

 装饰器在 Python 使用如此方便都要归因于 Python 的函数能像普通的对象一样能作为参数传递给其他函数,可以被赋值给其他变量,可以作为返回值,可以被定义在另外一个函数内。

__call__()方法  使实例能够像函数一样被调用

class Foo(object):
    def __init__(self, func):
        self._func = func

    def __call__(self):
        print ('class decorator runing')
        self._func()
        print ('class decorator ending')

@Foo
def bar():
    print ('bar')

bar()
def logged(func):
    def with_logging(*args, **kwargs):
        print func.__name__      # 输出 'f'    
        return func(*args, **kwargs)
    return with_logging

@logged
def f(x):
   """does some math"""
   return x + x * x
f(3)
#  f
#  12

1

原文地址:https://www.cnblogs.com/zhang1422749310/p/11825952.html