Python:__setattr__ 用于旧式 类?

Python: __setattr__ for old-style classes?

如何在旧式 class 上执行 __setattr__ 的等价操作?

如果您想为旧样式实例设置属性 class,您可以使用 setattr 内置函数,它应该适用于旧样式 class也是。例子-

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

您应该使用内置函数,例如任何类型的 class。

由于 original question 接受“...等效方法”,我想演示在旧式 classes 中实现特殊 __setattr__() 方法的正确方法.

tl;博士

在旧式 class 的 __setattr__(self, attr_name, attr_value) 方法中使用 self.__dict__[attr_name] = attr_value

__setattr__()遇见老式Class

有趣的是,Python 2.7 和 3 do 都调用 __setattr__() 由旧式 classes 定义的方法。然而,与新式 classes 不同,旧式 classes 不提供默认的 __setattr__() 方法。不出所料,这使旧式 classes 中的 __setattr__() 方法异常复杂。

在新式class的subclass__setattr__()中,通常会在末尾调用superclass__setattr__()来设置想要的属性。在旧式 class 的 subclass __setattr__() 中,这通常会引发异常;在大多数情况下,没有超级class__setattr__()。相反,必须手动设置特殊 __dict__ 实例变量所需的键值对。

例子或者它没有发生

考虑一个很棒的旧式 class,类似于短语 "The Black Goat of the Woods with a Thousand Young" 并定义 __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

黑暗中的不对称

奇怪的是,旧式 classes do 提供默认的 __getattr__() 方法。 Python 2.7 是如何允许这种令人厌恶的不对称现象存在的,这是没有人想过的——因为它同样可怕和可耻!

但确实如此。