Возможно ли переопределить поле __bases__
метакласса (то есть класс, полученный из type
) с использованием свойства get-set? Следующий код работает для получатьC.__bases__
, но не установки это:Переопределение __bases__ в метаклассе
class Meta(type):
@property
def __bases__(cls):
print('Getting __bases__ via Meta.__bases__')
return super().__bases__
@__bases__.setter
def __bases__(cls, value):
print('Setting __bases__ via Meta.__bases__')
super().__bases__ = value
class A: pass
class B: pass
class C(A, B, metaclass=Meta): pass
# >>> C.__bases__
# Getting __bases__ via Meta.__bases__
# (<class '__main__.A'>, <class '__main__.B'>)
# >>> C.__bases__ = (B, A)
# Setting __bases__ via Meta.__bases__
# AttributeError: 'super' object has no attribute '__bases__'
Я попробовал несколько замен для super()
в функции сеттера, но ни один из них не работает:
type.__setattr__(cls, '__bases__', value)
приводит к рекурсии.
object.__setattr__(cls, '__bases__', value)
дает TypeError: can't apply this __setattr__ to type object
Итак, что это сводится к тому, как установить cls.__bases__
поле, когда он омрачены собственности на метакласса. Есть идеи?
(Да, я знаю, что определение __bases__
свойства не оказывает никакого влияния на фактическое __mro__
класса, хотя это может быть организовано путем переопределения mro()
)
Нет, вы не можете. Зачем вам это нужно, какая проблема этого решения? –
И 'super()' поддерживает только дескрипторы без данных (так что только '__get__'). Нет '__set__' поддерживается, поэтому' super() .__ bas__ = value' попытается использовать атрибут '__bases__' в суперпрокси, а не в каком-либо базовом классе. '__bases__' не может быть изменен. –
Re: почему я хочу это сделать: идея заключается в реализации своего рода «прокси класса», который пересылает метод и атрибут доступа к прокси-классу путем копирования его '__mro__'. Было бы хорошо, если '__bases__' прокси-класса класса также соответствовал бы« __bases__ »прокси-класса, следовательно, необходимость его переопределения. –