У него был (на мой взгляд) глупый обходной путь.
Вот почему TypeError
не вызывается, когда __slots__
пусто, а наличие пустого атрибута __slots__
сохраняет «удивленное» поведение питона, которое выдает предупреждение при назначении атрибута, не определенного в __slots__
.
Итак, рассмотрим следующий метакласс :
class SlotBase(type):
def __new__(cls,name,bases,dctn):
if ('_slots_' in dctn) and not ('__slots__' in dctn):
dctn['__slots__'] = []
elif '__slots__' in dctn:
for base in bases:
if hasattr(base,'_slots_'):
dctn['__slots__'] += getattr(base,'_slots_')
return super().__new__(cls,name,bases,dctn)
Затем разверните на базовых классах.
class A(metaclass=SlotBase):
_slots_=['slot1'] #fake __slots__ attribute
classPropertyA = 'Some silly value'
def functA(self):
print('I\'m functA')
class B(metaclass=SlotBase):
_slots_=['slot2'] #fake __slots__ attribute
classPropertyB = 'Some other silly value'
def functB(self):
print('I\'m functB')
class C(A,B):
__slots__ = []
classPropertyC = 'Just another silly value'
Если мы выполним следующий код
c=C()
c.classPropertyC
c.classPropertyA
c.functA()
c.functB()
c.slot1='Slot exists then assignment is accepted'
c.slot3='Slot does not exists then assignment couldn\'t be accepted'
Это дает следующий вывод
Just another silly value
Some silly value
I'm functA
I'm functB
Traceback (most recent call last):
File "/tmp/slots.py", line 41, in <module>
c.slot3='Slot does not exists then assignment couldn\'t be accepted'
AttributeError: 'C' object has no attribute 'slot3'