获得应用于方法的Python 3类装饰器

时间:2015-12-11 17:08:23

标签: python python-3.x metaprogramming python-decorators

正如标题所述,我正在寻找一种装饰类的方法,这样当我调用方法时,装饰器就会应用于该调用。这背后的主要原因将允许我捕获函数调用及其参数传递。我没有沿着传统的方式来修饰单个方法的原因是这些方法可能不会提前知道,因为这些类将通过插件扩展。我也对其他实现开放不得不这个问题。

footer {
    position: relative;
}
.copyright{
    position: absolute;
    bottom: 0;
}

所以采用上面的装饰器并将其应用于类而不是方法。

伪代码示例:

from functools import wraps


def echo(fh):
    def func_wrapper(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            ret = func(*args, **kwargs)
            if ret is None:
                ret = "empty"
            fn_calls = []
            if args:
                fn_calls.append([func.__name__, args, ret])
            elif kwargs:
                fn_calls.append([func.__name__, kwargs, ret])
            else:
                raise ArgumentError
            collector(fh, fn_calls)
        return wrapper
    return func_wrapper

会返回类似的内容:['foo.bar','baz','无']

提前致谢...

1 个答案:

答案 0 :(得分:1)

如果你不喜欢元类,你可以使用类装饰器:

import functools

def _echoit(file, func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        file.write('Echoing func %s\n' % func.__name__)
        file.write('Echoing args %\n' % args)
        file.write('Echoing kwargs %s\n' % kwargs)
        return func(*args, **kwargs)
    return wrapper

def echo(file):
    def decorator(cls):
        attrs = vars(cls)
        for k in list(attrs.keys()):
             if callable(attrs[k]):
                 attrs[k] = _echoit(attrs[k], file)
        return cls
    return decorator

@echo(file_)
class Foo(object):
    def __init__(self):
        pass

    def bar(self, name):
        print("this is %s" % name)

foo = Foo()
foo.bar("baz")

如果这是针对插件系统的,那么带有自定义元类的基类将来可能会更具扩展性,并允许您使用需要重写的自定义抽象方法等。