Я изучал метаклассы, и мне было интересно, можно ли добавить новый атрибут для каждого класса, определенного в python, а не только для тех, которые явно наследуются от пользовательского метакласса.
Я могу добавить новый атрибут явно, используя пользовательский метакласс, подобный этому
class NewAttrMeta(type):
def __new__(cls, name, bases, attrs):
attrs['new_attr'] = 'new_thing'
return super().__new__(cls, name, bases, attrs)
class A(metaclass=NewAttrMeta):
...
print(A.new_attr)
$ 'new_thing'
Но возможно ли принудительно изменить подобное для каждого класса, который определен, а не только для тех, которые явно унаследовать от вашего пользовательского метакласса?
Я подумал, может быть, поскольку все классы имеют тип type
, если я перезаписал сам type
своим пользовательским метаклассом, тогда все новые классы могут наследоваться от него. А поскольку метаклассы являются подклассами type
, то все классы, определенные таким образом, будут по-прежнему действительны ...
class NewAttrMeta(type):
def __new__(cls, name, bases, attrs):
attrs['new_attr'] = 'new_thing'
return super().__new__(cls, name, bases, attrs)
type = NewMagicMeta
Но это работает только в том случае, если type
передается явно снова:
class A(type):
...
print(A.new_attr)
$ 'new_thing'
class B():
...
print(B.new_attr)
$ AttributeError: type object 'A' has no attribute 'new_attr'
С какой стати я пытаюсь это сделать? Я хотел посмотреть, смогу ли я локально реализовать версию отклоненного PEP 472: «Поддержка индексации с аргументами ключевых слов» путем переопределения метода __getitem__
каждого класса, который определил любую версию __getitem__
. Я делаю это только для удовольствия, поэтому мне будут интересны любые идеи или альтернативные способы сделать это (чем хакер тем лучше!).