- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一节课 __slots__
:
class A:
__slots__ = ('foo',)
如果我创建一个子类而不指定__slots__
,子类将有一个__dict__
:
class B(A):
pass
print('__dict__' in dir(B)) # True
有什么方法可以防止 B
有一个 __dict__
而不必设置 __slots__ = ()
?
最佳答案
@AKX的答案几乎是正确的。我认为 __prepare__
和元类确实是很容易解决这个问题的方法。
简单回顾一下:
__slots__
键,则该类将使用 __slots__
而不是 __dict__
。 __prepare__
将名称注入(inject)到类的命名空间之前。因此,如果我们简单地从 __prepare__
返回包含键 '__slots__'
的字典,那么类将(如果 '__slots__'
键在类主体的评估期间不会再次删除)使用 __slots__
而不是 __dict__
。因为 __prepare__
只是提供了初始命名空间,所以可以轻松覆盖 __slots__
或在类主体中再次删除它们。
因此默认情况下提供 __slots__
的元类看起来像这样:
class ForceSlots(type):
@classmethod
def __prepare__(metaclass, name, bases, **kwds):
# calling super is not strictly necessary because
# type.__prepare() simply returns an empty dict.
# But if you plan to use metaclass-mixins then this is essential!
super_prepared = super().__prepare__(metaclass, name, bases, **kwds)
super_prepared['__slots__'] = ()
return super_prepared
因此,每个具有此元类的类和子类(默认情况下)在其命名空间中都有一个空的 __slots__
,从而创建一个“带槽的类”(除了 __slots__
被故意删除)。
只是为了说明这是如何工作的:
class A(metaclass=ForceSlots):
__slots__ = "a",
class B(A): # no __dict__ even if slots are not defined explicitly
pass
class C(A): # no __dict__, but provides additional __slots__
__slots__ = "c",
class D(A): # creates normal __dict__-based class because __slots__ was removed
del __slots__
class E(A): # has a __dict__ because we added it to __slots__
__slots__ = "__dict__",
通过了 AKZ 回答中提到的测试:
assert "__dict__" not in dir(A)
assert "__dict__" not in dir(B)
assert "__dict__" not in dir(C)
assert "__dict__" in dir(D)
assert "__dict__" in dir(E)
并验证它是否按预期工作:
# A has slots from A: a
a = A()
a.a = 1
a.b = 1 # AttributeError: 'A' object has no attribute 'b'
# B has slots from A: a
b = B()
b.a = 1
b.b = 1 # AttributeError: 'B' object has no attribute 'b'
# C has the slots from A and C: a and c
c = C()
c.a = 1
c.b = 1 # AttributeError: 'C' object has no attribute 'b'
c.c = 1
# D has a dict and allows any attribute name
d = D()
d.a = 1
d.b = 1
d.c = 1
# E has a dict and allows any attribute name
e = E()
e.a = 1
e.b = 1
e.c = 1
正如评论(作者 Aran-Fey)所指出的,del __slots__
和将 __dict__
添加到 __slots__
之间是有区别的:
There's a minor difference between the two options:
del __slots__
will give your class not only a__dict__
, but also a__weakref__
slot.
关于python - 我怎样才能强制子类有 __slots__?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56579348/
首先让我说我了解槽和元类在 Python 中的工作方式。玩弄这两个,我遇到了一个有趣的问题。这是一个最小的例子: def decorator(cls): dct = dict(cls.__di
__slots__ 的目的是什么?在 Python 中——尤其是关于我什么时候想使用它,什么时候不想使用它? 最佳答案 In Python, what is the purpose of __slot
我在 Python 的输入系统和 __slots__ 之间有冲突。这是一个可重现的小例子。 from typing import TypeVar, Generic, Sequence T = Type
class Foo(object): __slots__ = ('a',) class Bar(Foo): @property def a(self): ret
我有一节课 __slots__ : class A: __slots__ = ('foo',) 如果我创建一个子类而不指定__slots__,子类将有一个__dict__: class B(A
我正在开发一个需要通过 __init__ 注入(inject)来为其赋予 __dict__ 属性的类,如下所示: class Torrent(Model): def __init__(self
我听说 __slots__ 通过避免字典查找使对象更快。我的困惑来自于 Python 是一种动态语言。在静态语言中,我们通过编译时优化将索引保存在我们运行的指令中,从而避免了对 a.test 的字典查
我需要用 None 初始化一个实例的所有插槽。如何获取派生类的所有插槽? 示例(不起作用): class A(object): __slots__ = "a" def __init__
所以,我正在阅读一些关于 Python 中元类的内容,以及如何使用 type()的三参数 alter-ego 用于动态创建类。但是,第三个参数通常是 dict。初始化要创建的类'__dict__变量。
考虑以下代码: from weakref import ref class Klass(object): # __slots__ = ['foo'] def __init__(self
通过学习《Python类变量和实例变量》一节,了解了如何动态的为单个实例对象添加属性,甚至如果必要的话,还可以为所有的类实例对象统一添加属性(通过给类添加属性)。 那么,Python 是否也允许动态地
早上好 我在尝试在我的一门类(class)中使用 __ 插槽 __ 时遇到问题。我想用它来优化 Classifier 对象的多个实例的创建。我正在使用 Python 3.7.1。 这行得通 class
当我运行这个(2.7.3)时,我得到这个输出: 'Slotted1' object has no attribute 'c' attribute c added to 我不明白 Slotted1 和
最近在学习Python,但是我有一个关于__slots__的问题。我认为是为了限制Class中的参数,同时也限制Class中的方法? 例如: from types import MethodType
最近给 friend 讲解了__slots__的用法。我想向他展示结果并使用了以下代码: import sys class Foo: __slots__ = 'a', 'b' def
我一直在玩弄 __slots__ 并稍微搜索一下,但我仍然对某些细节感到困惑: 我知道 __slots__ 生成某种描述符: >>> class C: ... __slots__ = ('x'
在类中创建结果对象时,是否可以在本例中使用__slots__?我想我可以通过将 '__slots__' 传递到 type 的第三个参数的字典中来让它工作: class GeocodeResult(ob
我读入了Usage of __slots__?在 Python 中使用 __slots__ 实际上可以节省时间。但是,当我尝试使用 datetime 查找所花费的时间时,结果却相反。 import d
我正在使用 Python 3.7 和 Django。我正在阅读 __slots__ .显然,__slots__ 可用于通过提前列出所有对象属性来优化大量此类对象的内存分配。 class MyClass
我正在编写一个配置卷的存储自动化模块。我没有传递在存储 Controller 上实际创建卷所需的六个或更多参数,而是使用 __slots__ 创建了一个参数类,它被传递到 create 方法中,如下所
我是一名优秀的程序员,十分优秀!