【发布时间】:2015-04-21 17:36:46
【问题描述】:
当我们装饰函数时,我们使用functools.wraps 使装饰的函数看起来像原来的一样。
当我们想装饰班级时,有什么可以做的吗?
def some_class_decorator(cls_to_decorate):
class Wrapper(cls_to_decorate):
"""Some Wrapper not important doc."""
pass
return Wrapper
@some_class_decorator
class MainClass:
"""MainClass important doc."""
pass
help(MainClass)
输出:
class Wrapper(MainClass)
| Some Wrapper not important doc.
|
| Method resolution order:
| Wrapper
| MainClass
| builtins.object
|
# ... no MainClass important doc below.
我尝试为基于functools.wraps 源代码的类装饰器编写等效包装,但我的实现不正确:
import functools
def wraps_cls(original_cls):
def wrapper(wrapper_cls):
"""Update wrapper_cls to look like original_cls."""
for attr in functools.WRAPPER_ASSIGNMENTS:
try:
value = getattr(original_cls, attr)
except AttributeError:
pass
else:
setattr(wrapper_cls, attr, value)
return wrapper_cls
return wrapper
def some_class_decorator(cls_to_decorate):
@wraps_cls(cls_to_decorate)
class Wrapper(cls_to_decorate):
"""Some Wrapper not important doc."""
pass
return Wrapper
@some_class_decorator
class MainClass:
"""MainClass important doc."""
pass
help(MainClass)
输出:
class MainClass(MainClass)
| MainClass important doc.
|
| Method resolution order:
| MainClass
| MainClass
| builtins.object
|
# ... MainClass doc is here but "Method resolution order" is broken.
有没有用未修饰的 MainClass 帮助输出完全替换修饰的 MainClass 帮助输出?
【问题讨论】:
-
您的装饰器返回一个新类,它是原始(包装)类的子类。您无法获得相同的方法解析顺序,因为您在层次结构中添加了一个额外的类。
-
谢谢,你的 wraps_cls 方法帮助我用参数包装一个类,同时保留类名。
-
使用
@functools.wraps(cls, updated=())可以让您免于编写自己的包装器。但它也遇到了同样的问题。
标签: python python-3.x python-decorators