在 Python 类中从 `__annotations__` 分配 `__slots__` 有什么缺点吗?

问题描述 投票:0回答:1

使用 Python 的类型注释,声明

__slots__
的类通常最终会重复类标识符。

一个简单的例子:

class Event:
    location: tuple[float, float]
    index: int

    __slots__ = (
        "location",
        "index",
    )

另一种方法是使用注释来声明插槽。

class Event:
    location: tuple[float, float]
    index: int

    __slots__ = tuple(__annotations__)

在 Python 3.10 及更高版本中,是否有任何理由避免从

__slots__
派生
__annotations__

python python-3.x slots type-annotation
1个回答
0
投票

我可以告诉你的三个问题使得这样的用法相当糟糕:

  • 这不支持属性的前向声明,因此
    __slots__
    必须放在最后:
    class A:
        __slots__ = tuple(__annotations__)
        a: int
    
    >>> A.__slots__
    ()
    
  • 涉及
    ClassVar
    的错误检测:
    from typing import ClassVar
    
    class A:
        a: ClassVar[int]
    
        __slots__ = tuple(__annotations__)
    
    >>> A.__slots__
    ('a',)
    
  • 类型检查器(至少 mypy)不理解它(参见 mypy Playground):
    class A:
        a: int
        __slots__ = ('a',)
    
        def __init__(self) -> None:
            self.asdf: str = ""  # Error
    
    class A_auto_slotted:
        a: int
        __slots__ = tuple(__annotations__)
    
        def __init__(self) -> None:
            self.asdf: str = ""  # No error
    

如果您注释

__slots__
并直接分配
__annotations__
(请注意,
__slots__
应该能够成为
dict
),也会发生一些模糊的情况,尽管这在实际代码中不太可能发生:

class A:
    __slots__: dict[str, object] = __annotations__
ValueError: '__slots__' in __slots__ conflicts with class variable
© www.soinside.com 2019 - 2024. All rights reserved.