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 позволил этой непристойной асимметрии противостоять, не имеет смысла думать - поскольку это одинаково отвратительно и постыдно!
Но это.