【发布时间】:2019-07-23 02:47:46
【问题描述】:
我想为使用插槽的对象添加属性。我知道这是一个 hack,不应该使用。
但是有没有办法绕过这个插槽限制?
【问题讨论】:
-
如果您详细说明为什么要这样做,它可能会帮助我们解决您的实际问题。
-
你想给实例加属性还是给类加槽?
我想为使用插槽的对象添加属性。我知道这是一个 hack,不应该使用。
但是有没有办法绕过这个插槽限制?
【问题讨论】:
没有。如果您没有将'__dict__' 声明为插槽之一,则该类具有固定的底层结构布局,没有空间用于动态定义的属性;您能做的最好的事情就是从头开始重新定义该类并替换它(并希望在您使用它之前没有人创建原始类的实例),或者创建一个子类(不必在正文,只是pass;如果它没有声明__slots__,它将正常以__dict__/__weakref__结束)并使用它来代替父类。
即使在定义类之后更改__slots__ 也无济于事;插槽在此时被烘焙到类中;你可以del MyClass.__slots__ 而不改变行为。
【讨论】:
您可以某种修改__slots__,方法是创建一个具有相同名称的子类,然后用其子类替换父类。请注意,您可以为在任何模块中声明和使用的类执行此操作,而不仅仅是您的!
另外请注意,这个问题已经回答过几次了。更多详情请见my answer here。
(其实你问的时候没有我的答案,但有其他答案的问题=)))
【讨论】:
这正是使用 __slots__ 所防止的,而且您似乎已经知道这一点,因为您已经提到尝试做您正在做的事情是您应该避免的黑客行为。
你基本上有两种选择;
不要使用__slots__。您将能够为您的心脏内容添加属性,并且根据您使用此类的方式,您可能甚至不会注意到性能差异。
预先添加属性,但将它们设置为 None(或一个标记值)并稍后填充它们(而不是稍后创建它们)。
如果您想使类的属性动态化 - 那么__slots__ 根本不适合您。
【讨论】: