gpt4 book ai didi

python - 装饰器在输入中采用一个类和不同的参数

转载 作者:太空宇宙 更新时间:2023-11-03 16:42:05 25 4
gpt4 key购买 nike

我想创建一个装饰器,将记录器添加到任何装饰类中。我成功了:

def logged(cls_to_decorate):
log_name = cls_to_decorate.__module__
logger = logging.getLogger(log_name)

setattr(cls_to_decorate, 'logger', logger)
return cls_to_decorate

其用法:

@logged
class TestFoo(TestCase):
def test_foo_function(self):
self.logger.debug("ciao!!")

现在假设我想向此装饰器传递一个附加参数,因此按如下方式使用它:

@logged(logging_level=logging.DEBUG)
class TestFoo(TestCase):
pass

我尝试使用函数/方法的装饰器语法(带有包装函数),但是当然,因为我们正在讨论类作为参数,所以它不起作用。

装饰器应该是这样的:

...
def logged(cls_to_decorate, logging_level=None):
logging.basicConfig(level=logging_level)

log_name = cls_to_decorate.__module__
logger = logging.getLogger(log_name)

setattr(cls_to_decorate, 'logger', logger)
return cls_to_decorate
...

注意:要装饰的对象是,而不是函数

解决方案python decorators with parameters应该适用,但我尝试了以下方法:

def logged(logging_level=None):
def class_decorator(cls_to_decorate):

# Do something with arguments
logging.basicConfig(level=logging_level)
log_name = cls_to_decorate.__module__
logger = logging.getLogger(log_name)

setattr(cls_to_decorate, 'logger', logger)
return cls_to_decorate
return class_decorator

但是每次我包装一个类来处理一些参数时都会出现错误:

E               TypeError: class_decorator() takes exactly 1 argument (2 given)

感谢您的帮助!

最佳答案

the answer here类的工作方式与函数完全相同,创建一个嵌套工厂函数:

def decorator(argument):
def real_decorator(class):
<DECORATOR CODE HERE>
return real_decorator

所以你会这样做:

def logged(logging_level):
def class_decorator(cls_to_decorate):
log_name = cls_to_decorate.__module__
logger = logging.getLogger(log_name)

setattr(cls_to_decorate, 'logger', logger)
return cls_to_decorate
return class_decorator

请注意,这意味着您必须调用装饰器才能使用它,仅使用@logged就会认为该类是logging_level 参数没有任何意义,您至少需要执行 @logged() 才能使其工作。

<小时/>

尽管您无论如何都使用关键字,但当调用缺少信息时,我想提供使用 functools.partial 的替代方案:

def logger(cls_to_decorate=None, logging_level=logging.DEBUG):
if cls_to_decorate is None:
return functools.partial(logger, logging_level=logging_level)

... #other code here

这样,当您执行 logger(existing_cls) 时,它可以正常工作,而当您执行 @logger(logging_level=logging.INFO) 时,它可以正常工作,并且只是 @logged 工作正常,唯一的陷阱是您不小心指定了该选项来代替类。

@logger(logging.INFO) #on no we passed a positional argument!!
class Test():pass

Traceback (most recent call last):
File "/Users/Tadhg/Documents/codes/test.py", line 25, in <module>
@logged(logging.INFO)
File "/Users/Tadhg/Documents/codes/test.py", line 19, in logged
log_name = cls_to_decorate.__module__
AttributeError: 'int' object has no attribute '__module__'

这不是信息最丰富的错误消息,尽管可以通过在某些时候添加 assertspectr.isclass(cls_to_decorate) 来改进它。

关于python - 装饰器在输入中采用一个类和不同的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36700477/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com