Доступ к статическим полям из декорированного класса
Пример полного кода:
def decorator(class_):
class Wrapper:
def __init__(self, *args, **kwargs):
self.instance = class_(*args, **kwargs)
@classmethod
def __getattr__(cls, attr):
return getattr(class_, attr)
return Wrapper
@decorator
class ClassTest:
static_var = "some value"
class TestSomething:
def test_decorator(self):
print(ClassTest.static_var)
assert True
При попытке выполнить тест, появляется ошибка:
test/test_Framework.py F
test/test_Framework.py:37 (TestSomething.test_decorator)
self = <test_Framework.TestSomething object at 0x10ce3ceb8>
def test_decorator(self):
> print(ClassTest.static_var)
E AttributeError: type object 'Wrapper' has no attribute 'static_var'
Можно ли получить доступ к статическим полям из декорированного класса?
2 ответа
Решение
Хотя ответ @martineau, вероятно, лучше решает конкретную проблему, которую вы пытаетесь решить, более общий подход может заключаться в использовании метакласса для переопределения метода экземпляра. __getattr__
на type
экземпляр (и классы являются экземплярами type
).
def decorator(class_):
class WrapperMeta(type):
def __getattr__(self, attr):
return getattr(class_, attr)
class Wrapper(metaclass=WrapperMeta):
def __init__(self, *args, **kwargs):
self.instance = class_(*args, **kwargs)
return Wrapper
Это позволяет просматривать атрибуты самого класса. WrapperMeta.__getattr__
,
Вы можете заставить его работать, заставив декоратор создать класс, производный от декорируемого.
Вот что я имею в виду:
def decorator(class_):
class Wrapper(class_):
def __init__(self, *args, **kwargs):
self.instance = super().__init__(*args, **kwargs)
return Wrapper
@decorator
class ClassTest:
static_var = "some value"
print(ClassTest.static_var) # -> some value