#python
#python
Вопрос:
Я возился с динамическими атрибутами и заметил, что не смогу использовать атрибут __dict__, если я создам объект непосредственно из класса object(), но если я создам новый класс, который является прямым потомком object, я смогу получить доступ к атрибуту __dict__. В чем разница?
Примеры:
# This gives an AttributeError
o = object()
o.__dict__
# This works: prints {}
class myClass(object):
pass
o = myClass()
o.__dict__
Комментарии:
1. Возиться с
__dict__
напрямую почти всегда не нужно и плохая идея. Название динамических атрибутов обычно лучше оформлять как ключи словаря, но в некоторых случаях это оправдано — но вы можете просто использоватьsetattr
в этих случаях.
Ответ №1:
object
реализован на C и не имеет __dict__
атрибута. (Не все объекты Python также имеют это; посмотрите __slots__
).
Комментарии:
1. @Jamie Обратите внимание, что вы также не можете назначать случайные атрибуты экземпляру, полученному в результате выполнения
object()
, в то время как вы можете с экземпляромmyClass
. На самом деле вы мало что можете сделать с экземпляромobject
, который не является экземпляром какого-либо другого класса.
Ответ №2:
Я не совсем уверен, почему это работает для вашего класса, но не для исходного object
класса. Я бы предположил, что когда ваш класс инициализируется, он создает __dict__ .
Используя этот код:
class Test(object):
def __init__(self):
pass
def main():
print 'OBJECT:', dir(object())
print
print 'TEST:', dir(Test())
return
Пришел к такому выводу:
OBJECT: ['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__']
TEST: ['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__']
Как вы можете видеть, __dict__, __module__ и __weakref__ находятся в тестовом объекте, но не в базовом объекте
Комментарии:
1. Это неотъемлемая часть Python — от определения класса зависит, хотят ли они предоставлять атрибут dict или нет (его исключение может сэкономить изрядное количество места на экземпляр). Поскольку dict включен в экземпляры по умолчанию, вы должны предпринять конкретные действия во время определения класса, чтобы избежать его предоставления.