2015-01-07 3 views
2

В примерах исходных и SO ответы, которые имеют некоторую степень Python объект самоанализа, общая картина:Зачем использовать getattr() вместо __dict__ при доступе к атрибутам объекта Python?

getattr(some_object, attribute_name_string) 

Есть причина, почему эта модель является предпочтительной:

some_object.__dict__[attribute_name_string] 

, который, кажется, более конкретно показывать, что происходит? Это потому, что последнее слишком близко к конкретной реализации в CPython, которое может быть изменено?

NB Оригинальный вопрос неправильно определил популярные идиомы как:

some_object.__getattr__(attribute_name_string) 
+2

[Для соблюдения протокола дескриптора.] (Https://docs.python.org/2/reference/datamodel.html#object.__setattr__) –

+0

@AshwiniChaudhary: Спасибо, читаю связанные документы. – zehnpaard

+0

В какой-то мере причина использования 'getattr' - это * точно * причина, которую вы определили, как в поддержку' __dict__': она прямо показывает, что происходит, и тем самым нарушает инкапсуляцию. –

ответ

11

some_object.__getattr__ является не общий шаблон. getattr(some_object, attribute_name_string) - это правильный способ динамического доступа к атрибутам.

Не все экземпляры имеют a __dict__ атрибут; класс, который использует __slots__, например, не будет иметь этого атрибута. Затем атрибуты необязательно будут найдены на экземпляре, но вместо этого являются атрибутами класса. getattr() найдут их, глядя на __dict__, не найдут их. Атрибуты класса могут также зависеть от descriptor protocol.

Может быть использован для прямого доступа к крюку __getattr__ или атрибуту __dict__, но это только специализированное использование. __getattr__ используется, только если атрибут не был найден в другом месте, например (так для атрибутов не присутствует в классе или в instance.__dict__).

+0

Извините, мой плохой - вы правы, это был «getattr (obj, attr)», а не «obj .__ getattr__», который я продолжаю видеть. Спасибо за просветляющий ответ. – zehnpaard

 Смежные вопросы

  • Нет связанных вопросов^_^