__dict__
не «конвертирует» объект в dict
(в отличие от __int__
, __str__
и т. Д.), Именно там хранятся атрибуты (доступные для записи) объекта.
Я думаю, что ваша реализация достаточно эффективна. Рассмотрим этот упрощенный пример:
import dis
class Foo:
def __init__(self, a):
self.a = a
def to_dict(self):
return {'a': self.a}
foo = Foo(1)
dis.dis(foo.to_dict)
dis.dis('foo.__dict__')
Мы можем видеть, что Python просматривает атрибуты и каждый раз создает новый dict
(плюс вам нужно позвонить на .to_dict
, не показанный здесь):
7 0 LOAD_CONST 1 ('a')
2 LOAD_FAST 0 (self)
4 LOAD_ATTR 0 (a)
6 BUILD_MAP 1
8 RETURN_VALUE
при доступе к существующему атрибуту намного проще:
1 0 LOAD_NAME 0 (foo)
2 LOAD_ATTR 1 (__dict__)
4 RETURN_VALUE
Однако вы можете сохранить свое пользовательское представление в экземпляре, получив тот же точный байт-код, что и с __dict__
, но тогда вам нужно будет корректно обновить его при всех изменениях до Foo
(что будет стоить некоторой скорости и памяти). Если в вашем случае использования обновления встречаются редко, это может быть приемлемым компромиссом.
В вашем примере, простой вариант - переопределить __getattribute__
, но я предполагаю, что Foo
имеет другие атрибуты, поэтому иметь сеттеры, вероятно, будет удобнее:
class Foo:
def __init__(self, a):
self.dict = {}
self.a = a
@property
def a(self):
return self._a
@a.setter
def a(self, value):
self._a = value
self.dict['a'] = value
foo = Foo(1)
print(foo.dict) # {'a': 1}
foo.a = 10
print(foo.dict) # {'a': 10}