#python #python-3.x
#python #python-3.x
Вопрос:
В следующем простом коде Python:
>>> class C:
... class_level_var = 5
...
>>> C.__dict__
mappingproxy({'__module__': '__main__', 'class_level_var': 5, '__dict__': <attribute '__dict__' of
'C' objects>, '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None})
>>> #trying to reassign C.__dict__:
... C.__dict__ = None
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
AttributeError: attribute '__dict__' of 'type' objects is not writable
>>>
Вызов __dict__
on C
соединяется с __dict__
of type
, хотя C
сам имеет прямое __dict__
отношение к нему, как показано в выводе выше: « '__dict__': <attribute '__dict__' of 'C' objects>
«. Обратите внимание на сообщение об ошибке при присвоении None
, указывающее, что атрибут принадлежит type
, а не C
‘s.
Мой вопрос: не должны ли атрибуты объектов (class C
) иметь приоритет над их атрибутами класса (class type
)?
Ответ №1:
Вы неправильно интерпретируете сообщение об ошибке.
Вы думаете, что сообщение об ошибке ссылается на атрибут type.__dict__
, но когда оно говорит
AttributeError: attribute '__dict__' of 'type' objects is not writable
это означает, что __dict__
атрибут экземпляров type
недоступен для записи. C
сам по себе является экземпляром type
, и его __dict__
атрибут недоступен для записи.
Возможно, вы также захотите прочитать о протоколе дескриптора. Поиск атрибута для __dict__
атрибута объекта управляется дескриптором для __dict__
в классе объекта или классе-предке. Поскольку C
это экземпляр type
, поиск C.__dict__
управляется дескриптором, принадлежащим type
. Этот дескриптор управляет тем, что происходит, когда вы читаете или (пытаетесь) записать атрибут, и это то, что говорит, что вы не можете назначить C.__dict__
.
'__dict__': <attribute '__dict__' of 'C' objects>
Запись, которую вы видели в C.__dict__
, нет C.__dict__
; это дескриптор, который управляет __dict__
атрибутом экземпляров C
.
Комментарии:
1. Я полностью осознаю, что это дескриптор. И дескриптор, который (type.__dict__) является тем, что здесь оценивается, а не тем, что в классе C. Сообщение об ошибке здесь имеет общий смысл. «Сам C является экземпляром типа» — я согласен. «и его атрибут dict недоступен для записи». — Нет, я не думаю, что это тот, он ссылается на атрибут «type», который по-разному переводится для разных объектов, т. Е. Причина, По которой используется дескриптор.
2. атрибут @Searcherer:
C
__dict__
недоступен для записи, потому что дескриптор дляC.__dict__
(который является дескриптором вtype.__dict__
, а не дескриптором вC.__dict__
) говорит, что он недоступен для записи. Вы ожидаете, что дескриптор inC.__dict__
будет использоваться по какой-то причине? Это неправильный дескриптор.'__dict__'
Запись вC.__dict__
неC
__dict__
является атрибутом.3. Вы не знаете правил для дескрипторов данных?
__dict__
дескрипторы — это дескрипторы данных, и дескриптор данных, найденный при поиске в классе объекта, имеет приоритет над всем, что найдено в собственном dict объекта. В данном случае это означает, что дескриптор, найденный вtype.__dict__
, имеет приоритет над'__dict__'
записью вC.__dict__
при поискеC.__dict__
атрибута.4. Вероятно, мне следует углубиться в дескрипторы, прежде чем углубляться в это и тратить ваше время. .. при необходимости отправит ответ. Я ценю ваше руководство (-: