向装饰器添加参数会删除cls参数

时间:2019-10-09 09:22:20

标签: python logging decorator

我要按照here的说明在我的烧瓶应用程序中记录MongoEngine文档。但我也希望能够排除此文档类具有的某些属性。

如果我给装饰器的apply函数附加了一个参数excludes,则不会再给出cls参数。

Traceback (most recent call last):
  File ".../test.py", line 26, in <module>
    @__log_update.apply(excludes=[])
TypeError: apply() missing 1 required positional argument: 'cls'

在简化代码中

def handler(*events):
    """
    Signal decorator to allow use of callback functions as class decorators.
    """
    def decorator(fn):
        def apply(cls, excludes=[]):
            for exclude in excludes:
                print(exclude)

            for event in events:
                event.connect(fn, sender=cls)
            return cls

        fn.apply = apply
        return fn

    return decorator

@handler()
def __log_update(*args, **kwargs):
    pass


@__log_update.apply(excludes=['testString'])
class Test(object):
    testString = ''
    testInt = 0

但是,当仅使用@__log_update.apply而没有任何参数时,将给出cls参数,并且应为<class '__main__.Test'>

我都需要记录日志。

1 个答案:

答案 0 :(得分:1)

关于装饰器的工作原理。

以这种方式应用时(无论有无参数):

@__log_update.apply()

调用的结果应为 decorator 本身,然后将其应用于基础 class
您需要一个额外的图层,该图层将使.apply()函数返回类装饰器:

def handler(*events):
    """
    Signal decorator to allow use of callback functions as class decorators.
    """
    def decorator(fn):
        def apply(excludes=[]):
            def class_decor(cls):
                for exclude in excludes:
                    print(exclude)

                for event in events:
                    event.connect(fn, sender=cls)
                return cls
            return class_decor

        fn.apply = apply
        return fn

    return decorator

@handler()
def __log_update(*args, **kwargs):
    pass


@__log_update.apply(excludes=['testString'])
class Test(object):
    testString = ''
    testInt = 0
相关问题