问题描述
我正在尝试创建一个 ContextDecorator。这是我的代码:
class CmTag(ContextDecorator):
def __init__(self,cm_tag_func):
self.cm_tag_func = cm_tag_func
def __enter__(self):
return self
def __exit__(self,exc_type,exc_value,tb):
if exc_type is not None:
traceback.print_exception(exc_type,tb)
else:
name = self.cm_tag_func.__name__
print(name)
def __call__(self,**kwargs):
name = self.cm_tag_func.__name__
print(name)
print(kwargs)
self.cm_tag_func(**kwargs)
@CmTag
def testing(**kwargs):
pass
with testing(foo='bar') as t:
print('a test')
我希望输出是:
testing
{'foo':'bar'}
a test
testing
也就是说,它首先打印函数的名称。然后将 kwargs
作为字典打印出来。
然后它打印出上下文管理器中的任何内容,在这种情况下是“测试”。最后在退出时,它再次打印出函数的名称。
相反,它说:
testing
{'foo': 'bar'}
Traceback (most recent call last):
File "/workspace/sierra/src/sierra/test.py",line 32,in <module>
with testing(foo='bar') as t:
AttributeError: __enter__
我看到其他解决方案说 __enter__
未定义。但我已经在这里完成了。
我该如何解决这个问题?谢谢。
解决方法
在线
with testing(foo='bar') as t:
print('a test')
由于 testing
是 CmTag
的对象,因此您执行对 __call__
的调用,但是,您在该方法中返回 None
而不是返回 self
.
在该方法的末尾添加 return self
将修复它。