Python中类装饰器的2种类型

python的类装饰器实现有2种类型

  • 不带参数的类装饰器
  • 带参数的类装饰器

首相要明确,实现类装饰器,要实现类的魔术方法__init__和__call__,下面简单用例子介绍不带参数的类装饰器。

import time

# 不带参数的类装饰器,用于计算被装饰的方法所用时间
class Foo(object):
	# init中要带入func
    def __init__(self, func):
        self._func = func

    def __call__(self, *args, **kwargs):
        start_time = time.time()
        self._func(*args, **kwargs)
        end_time = time.time()
        print('spend is {}'.format(end_time - start_time))

@Foo  # bar = Foo(bar)
def bar(a):
    print('【{}】bar..'.format(a))
    time.sleep(2)


bar(123)

运行一下

> python3 test.py

输出如下

【123】bar..
spend is 2.0002646446228027

下面实现带参数的类装饰器,最大的不同就是在__init__中不再传入被装饰的方法func,把func转移到__call__中接收,并且在__init__中接收参数

import time

# 带参数的类装饰器,用于计算被装饰的方法所用时间
class Foo(object):
	# init方法只用来接收参数
    def __init__(self, info_="info"):
        self._info = info_

	# call方法接收被装饰方法func
    def __call__(self, func):
    	# 方法中如果带有参数,则写到wraps中作为可变参数传入,并传到func中
        def wraps(*args, **kwargs):
            print(self._info)
            start_time = time.time()
            func(*args, **kwargs)
            end_time = time.time()
            print('spend is {}'.format(end_time - start_time))
        return wraps


@Foo("【message】")  # bar = Foo(bar)
def bar(a):
    print('【{}】bar..'.format(a))
    time.sleep(2)


bar(123)

运行一下

> python3 test.py

输出如下

【message】
【123】bar..
spend is 2.000244617462158

你可能感兴趣的:(Python)