Python装饰器

93 阅读2分钟

Python装饰器是一种强大的工具,它允许我们以一种非侵入式的方式修改函数的行为。然而,装饰器有时会让人难以理解,尤其是当它们使用类时。在本文中,我们将研究两个使用类的Python装饰器的例子,并解释它们是如何工作的。

huake_00066_.jpg 2. 解决方案 第一个例子是一个名为donothing的装饰器,它不执行任何操作。它的主要目的是演示装饰器的基本用法。第二个例子是一个名为checkforkeysinparams的装饰器,它检查函数的参数是否包含一组必需的键。

对于第一个例子,donothing装饰器的工作原理如下:

  • 当我们使用@donothing装饰函数printer时,Python会创建一个donothing类的实例,并将printer函数作为参数传递给它的__init__方法。
  • __init__方法将printer函数存储在一个名为func的属性中。
  • 当我们调用printer函数时,它的__call__方法会被调用。__call__方法返回func函数的调用,并将参数传递给它。

对于第二个例子,checkforkeysinparams装饰器的工作原理如下:

  • 当我们使用@checkforkeysinparams(['name', 'pass', 'code'])装饰函数complex_function时,Python会创建一个checkforkeysinparams类的实例,并将complex_function函数作为参数传递给它的__init__方法。
  • __init__方法将['name', 'pass', 'code']存储在一个名为required的属性中。
  • 当我们调用complex_function函数时,它的__call__方法会被调用。__call__方法创建一个内部函数wrapperwrapper函数检查params参数是否包含required属性中指定的所有键。如果缺少任何键,它将引发TypeError异常。如果没有缺少任何键,它将调用func函数,并将params参数传递给它。

以下是一些代码示例:

# This does nothing.
class donothing(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        return self.func(*args, **kwargs)

@donothing
def printer(text):
    print(text)

printer('hello world')

# The printer function is now an alias for the donothing instance created, so
# the preceding was the same as:
#
# instance = donothing(printer)
# instance('hello world')
#


# Next example:

class checkforkeysinparams(object):
    def __init__(self, required):
        self.required = set(required)

    def __call__(self, params):
        def wrapper(params):
            missing = self.required.difference(params)
            if missing:
                raise TypeError('Missing from "params" argument: %s' % ', '.join(sorted(missing)))
        return wrapper


# Apply decorator class, passing in the __init__'s 'required' argument.

@checkforkeysinparams(['name', 'pass', 'code'])
def complex_function(params):
    # Obviously these three are needed or a KeyError will be raised.
    print(params['name'])
    print(params['pass'])
    print(params['code'])


# Create params to pass in. Note, I've commented out one of the required params.

params = {
    'name': 'John Doe',
    'pass': 'OpenSesame',
    #'code': '1134',
}

# This call will output: TypeError: Missing from "params" argument: code

complex_function(params=params)

希望这些例子能帮助您更好地理解Python装饰器。