Python: __setattr__ для классов в старом стиле?

Как я могу выполнить эквивалент __setattr__ в классе старого стиля?

2 ответа

Решение

Если вы хотите установить атрибут для экземпляра класса старого стиля, вы можете использовать setattr встроенная функция, она должна работать и для классов старого стиля. Пример -

>>> class Foo:
...     def __init__(self,blah):
...             self.blah=blah
... 
>>> foo = Foo("Something")
>>> foo.blah
'Something'
>>> setattr(foo,'blah','somethingElse')
>>> foo.blah
'somethingElse'

Вы должны использовать встроенную функцию, например, для любого типа класса.

Поскольку Mark Harrison принимает "... эквивалентные методы", я хотел бы продемонстрировать надлежащие средства реализации специальных __setattr__() метод в классах старого стиля.

ТЛ; др

использование self.__dict__[attr_name] = attr_value в __setattr__(self, attr_name, attr_value) метод класса старого стиля.

__setattr__() Встречается в старом стиле

Интересно, что оба Python 2.7 и 3 делают вызов __setattr__() методы, определенные классами старого стиля. В отличие от классов нового стиля, классы старого стиля не предоставляют никаких значений по умолчанию __setattr__() метод. Ни для кого не удивительно, это ужасно усложняет __setattr__() методы в классах старого стиля.

В подклассе __setattr__() класса нового стиля, суперкласс __setattr__() обычно вызывается в конце, чтобы установить нужный атрибут. В подклассе __setattr__() из класса старого стиля это обычно вызывает исключение; в большинстве случаев нет суперкласса __setattr__(), Вместо этого желаемая пара ключ-значение специального __dict__ переменная экземпляра должна быть установлена ​​вручную.

Пример или не случилось

Рассмотрим большой класс в старом стиле, напоминающий фразу "Черная коза леса с тысячей молодых" и определяющий __setattr__() префикс переданного имени атрибута la_:

class ShubNiggurath:
    def __setattr__(self, attr_name, attr_value):
        # Do not ask why. It is not of human purport.
        attr_name = 'la_' + attr_name

        # Make it so. Do not call
        # super(ShubNiggurath, self).__setattr__(attr_name, attr_value), for no
        # such method exists.
        self.__dict__[attr_name] = attr_value

Асимметрия во тьме

Любопытно, что классы старого стиля предоставляют стандартное значение __getattr__() метод. То, как Python 2.7 позволил этой непристойной асимметрии противостоять, не имеет смысла думать - поскольку это одинаково отвратительно и постыдно!

Но это.

Другие вопросы по тегам