Когда мы декорируем функцию, мы используем 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?
@functools.wraps(cls, updated=())
спасло бы вас от написания собственной оболочки. Хотя страдает от той же проблемы. - person Adrien H   schedule 19.02.2020