Согласно Python 2.7.12 документации:Зачем использовать объект .__ setattr __ (self, name, value) только в классах нового стиля?
Если
__setattr__()
хочет присвоить атрибут экземпляра, он должен не просто выполнитьself.name = value
- это вызовет рекурсивный вызов к себе. Вместо этого он должен вставить значение в словарь атрибутов экземпляра, например,self.__dict__[name] = value
. Для классов новых классов, а не для доступа к экземпляру словаря, он должен вызывать метод базового класса с тем же именем, напримерobject.__setattr__(self, name, value)
.
Однако следующий код работает, как и следовало ожидать:
class Class(object):
def __setattr__(self, name, val):
self.__dict__[name] = val;
c = Class()
c.val = 42
print c.val
Я знаю super(Class, obj).__setattr__(name, value)
может обеспечить __setattr__
методы всех базовых классов назвать, но классический класс может наследовать от классов баз. Так почему это рекомендуется только для новых классов стиля?
Или, с другой стороны, почему это не рекомендуется для классических классов?
* Так почему же это рекомендуется только для новых классов стиля? * Вызов '__setattr__' вместо работы с словарем экземпляра напрямую позволяет суперклассу« контролировать »происходящее. Подумайте об этом подходе в качестве преимущества новых классов стиля.Вероятно, это рекомендуется для всех классов, но классы старого стиля, которые не наследуют *, не имеют * суперкласса с вызываемым методом '__setattr__'. – jedwards
@jedwards Да, потому что для классических классов нет 'classobj .__ setattr__', а для новых классов стилей - только' object .__ setattr__'. –
Вы совершенно правы. Мое мнение состояло в том, что я рассматривал предложение, которое вы придаете жирным шрифтом, а не столько отвращение от непосредственного использования экземпляра dict (как вы показали, во многих случаях он отлично работает, и, как показал Мартийн, бывают случаи, когда он не будет), но больше * поощрения * использовать '__setattr__', что позволяет контролировать суперкласс и * использовать более новые функции, такие как дескрипторы. Извините, если я был неясен :) – jedwards