Python 2.7: object.__setattr__ 是做什么的?
Python 2.7: What does object.__setattr__ do under the hood?
在 Python 2.7 中,我可以声明新样式 class 并使用 object.__setattr__
:
设置属性
class A (object):
def __init__ (self):
object.__setattr__(self, 'foo', 'bar')
A().foo # 'bar'
但是,这在旧式中不起作用 class:
class B:
def __init__ (self):
object.__setattr__(self, 'foo', 'bar')
B().foo
TypeError: can't apply this __setattr__ to instance object
我知道旧式 classes 不支持这种行为,但我不知道为什么它不起作用。
当我在新式 class 上调用 object.__setattr__
而旧式 classes 不会发生时,幕后发生了什么?
请注意,我没有将此代码用于任何用途,我只是想了解它。
object.__setattr__
方法包括一个特定的检查以确保传入的 self
确实是对象(或重用相同 C 函数的另一个对象)的 (subclass)直接地)。该测试不允许传入任何其他内容,包括旧式实例。
检查是为了防止 object.__setattr__
被用来修改 内置类型 (称为 Carlo Verre hack,以其发现者命名。
没有显式检查(或者如果你编译 Python 禁用它),你可以这样做:
>>> object.__setattr__(str, 'lower', str.upper)
>>> "This is why we can't have nice things".lower()
"THIS IS WHY WE CAN'T HAVE NICE THINGS"
参见hackcheck()
function, and the original Python-dev discussion。
旧式实例对象没有通过测试只是一个副作用。
请注意,您想要调用 object.__setattr__
的 唯一 原因是,如果您有一个实现 __setattr__
的基础 class ] 你需要绕过的方法。对于旧式实例,您可以改用 self.__dict__[name] = value
。
类型 - 不是旧式 class,而是所有旧式实例的类型是 types.InstanceType
。这种类型是用 C 编写的,并实现了它自己的 __setattr__
。 Python 将拒绝将一种 C 类型的 __setattr__
应用于具有不同 C 级别 __setattr__
的 C 类型的实例,作为保护 C 数据结构一致性的安全措施。
在 Python 2.7 中,我可以声明新样式 class 并使用 object.__setattr__
:
class A (object):
def __init__ (self):
object.__setattr__(self, 'foo', 'bar')
A().foo # 'bar'
但是,这在旧式中不起作用 class:
class B:
def __init__ (self):
object.__setattr__(self, 'foo', 'bar')
B().foo
TypeError: can't apply this __setattr__ to instance object
我知道旧式 classes 不支持这种行为,但我不知道为什么它不起作用。
当我在新式 class 上调用 object.__setattr__
而旧式 classes 不会发生时,幕后发生了什么?
请注意,我没有将此代码用于任何用途,我只是想了解它。
object.__setattr__
方法包括一个特定的检查以确保传入的 self
确实是对象(或重用相同 C 函数的另一个对象)的 (subclass)直接地)。该测试不允许传入任何其他内容,包括旧式实例。
检查是为了防止 object.__setattr__
被用来修改 内置类型 (称为 Carlo Verre hack,以其发现者命名。
没有显式检查(或者如果你编译 Python 禁用它),你可以这样做:
>>> object.__setattr__(str, 'lower', str.upper)
>>> "This is why we can't have nice things".lower()
"THIS IS WHY WE CAN'T HAVE NICE THINGS"
参见hackcheck()
function, and the original Python-dev discussion。
旧式实例对象没有通过测试只是一个副作用。
请注意,您想要调用 object.__setattr__
的 唯一 原因是,如果您有一个实现 __setattr__
的基础 class ] 你需要绕过的方法。对于旧式实例,您可以改用 self.__dict__[name] = value
。
类型 - 不是旧式 class,而是所有旧式实例的类型是 types.InstanceType
。这种类型是用 C 编写的,并实现了它自己的 __setattr__
。 Python 将拒绝将一种 C 类型的 __setattr__
应用于具有不同 C 级别 __setattr__
的 C 类型的实例,作为保护 C 数据结构一致性的安全措施。