向使用 __slots__ 的对象添加属性
Add an attribute to an object which uses __slots__
我想给一个使用插槽的对象添加一个属性。我知道这是一个 hack,不应该使用。
但是有没有办法绕过插槽的这种限制?
没有。如果您没有将 '__dict__'
声明为插槽之一,则 class 具有固定的底层结构布局,没有 space 用于动态定义的属性;你能做的最好的事情就是从头开始重新定义 class 并替换它(并希望在你到达它之前没有人制作原始实例),或者制作一个 subclass (那不不必在正文中做任何特殊的事情,只需 pass
;如果它没有声明 __slots__
,它将像往常一样以 __dict__
/__weakref__
结束)和使用它代替父 class.
即使在定义 class 之后更改 __slots__
也不会做任何事情;插槽在那时被烘焙到 class 中;你可以 del MyClass.__slots__
不改变行为。
这正是使用 __slots__
所阻止的,而且您似乎已经知道这一点,因为您已经提到尝试做您正在做的事情是您应该避免的黑客行为。
你基本上有两个选择;
不要使用 __slots__
。您将能够随心所欲地添加属性,并且根据您使用它的方式 class,您甚至可能不会注意到性能差异。
添加属性 up-front,但将它们设置为 None
(或标记值)并稍后填充它们(而不是稍后创建它们)。
如果您试图使 class 上的属性动态化 - 那么 __slots__
根本不适合您。
您可以某种修改__slots__
,方法是创建同名的子class,然后用其子项替换父项class .请注意,您可以为 classes 在任何模块 中声明和使用 执行此操作,而不仅仅是您的!
另请注意,这个问题已经回答过几次了。有关详细信息,请参阅 my answer here。
(其实你问的时候我没有回答,但是有其他回答的问题=)) )
我想给一个使用插槽的对象添加一个属性。我知道这是一个 hack,不应该使用。
但是有没有办法绕过插槽的这种限制?
没有。如果您没有将 '__dict__'
声明为插槽之一,则 class 具有固定的底层结构布局,没有 space 用于动态定义的属性;你能做的最好的事情就是从头开始重新定义 class 并替换它(并希望在你到达它之前没有人制作原始实例),或者制作一个 subclass (那不不必在正文中做任何特殊的事情,只需 pass
;如果它没有声明 __slots__
,它将像往常一样以 __dict__
/__weakref__
结束)和使用它代替父 class.
即使在定义 class 之后更改 __slots__
也不会做任何事情;插槽在那时被烘焙到 class 中;你可以 del MyClass.__slots__
不改变行为。
这正是使用 __slots__
所阻止的,而且您似乎已经知道这一点,因为您已经提到尝试做您正在做的事情是您应该避免的黑客行为。
你基本上有两个选择;
不要使用
__slots__
。您将能够随心所欲地添加属性,并且根据您使用它的方式 class,您甚至可能不会注意到性能差异。添加属性 up-front,但将它们设置为
None
(或标记值)并稍后填充它们(而不是稍后创建它们)。
如果您试图使 class 上的属性动态化 - 那么 __slots__
根本不适合您。
您可以某种修改__slots__
,方法是创建同名的子class,然后用其子项替换父项class .请注意,您可以为 classes 在任何模块 中声明和使用 执行此操作,而不仅仅是您的!
另请注意,这个问题已经回答过几次了。有关详细信息,请参阅 my answer here。
(其实你问的时候我没有回答,但是有其他回答的问题=)) )