Вы не хотите использовать класс __dict__
вообще, в большинстве случаев (это разделяется между всеми экземплярами, помните), и вы почти наверняка не хотите супертип-х __dict__
, учитывая, что (как вы только что обнаружили) его не обязательно иметь его.
>>> class One:
... def __init__(self):
... print(super().__dict__)
...
>>> one = One()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
AttributeError: 'super' object has no attribute '__dict__'
Как сообщают, object
не __dict__
своих собственных. Это потому, что object
случаев, будучи встроенными типами, которые не могут приобретать дополнительные атрибуты, так object
жестко закодировано, чтобы запретить его:
>>> object().someattr = "hello"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'someattr'
>>>
При создании подкласса объекта в вашей программе, однако, его экземпляры могут принимать произвольные атрибуты, которые хранятся в экземпляре __dict__
.
>>> class Two:
... def __init__(self):
... print(self.__dict__)
...
>>> two = Two()
{}
>>> two.someattr = "hello"
>>> two.__dict__
{'someattr': 'hello'}
>>>
Обратите внимание, что механизм наследования делает Two
класс, как представляется, все атрибуты object
. dir()
функция позволяет просматривать пространство имен объекта, измененная наследования:
>>> dir(Two)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__']
Picking случайный атрибут, мы можем убедиться, что методы, присутствующие на Two
фактически унаследовали от object
:
>>> Two.__delattr__ is object.__delattr__
True
>>>
Может попробовать перехват '__getattribute__'? – Kupiakos
У меня на самом деле была ошибка. Я смешивал '__getattr__' с' __getattribute__'. –
Да, перехват '__getattribute__' достаточно. –