Python 打字:我应该在 class 中为 __slots__ 添加类型注释吗?

Python Typing: Should i add type annotations for __slots__ in my class?

我有一个关于在 python 内输入的问题。

警告:这个问题不是 __slots__ type annotations for Python / PyCharm 的重复问题,因为主题是关于实用程序而不是 pycharm 问题,不过如你所见,这是我后面提到的优点之一。


首先,我有一个 class Collections 来对我的主数据库(mongo 数据库)中的所有 collection 进行分组:

class Collections(StaticClassList):
    """A class to group all mongo collections from main database."""
    __slots__: Tuple[str, ...] = (
        "plugins", "prefixes", "reaction_roles", "welcome", "verify",
        "chatbot", "chatbot", "permissions"
    )

collections: Collections = Collections(database.axiol)

继承自class:

class StaticClassList(ABC):
    __instances = set()

    def __init__(self, base) -> None:
        ...

        for attr_name in self.__slots__:
            setattr(
                self, attr_name,
                base['_'.join(map(str.capitalize, attr_name.split()))]
            )

    ...

速记:这个摘要class被多个classes和__init__方法使用减少到必要的最低限度这是两个原因 ...


我的问题是我是否应该如下添加这些类型注释:

. class Collections(StaticClassList):
.     """A class to group all mongo collections from main database."""
.     __slots__: Tuple[str, ...] = (
.         "plugins", "prefixes", "reaction_roles", "welcome", "verify",
.         "chatbot", "chatbot", "permissions"
.     )
. 
+     plugins: AsyncIOMotorCollection
+     prefixes: AsyncIOMotorCollection
+     reaction_roles: AsyncIOMotorCollection
+     welcome: AsyncIOMotorCollection
+     verify: AsyncIOMotorCollection
+     chatbot: AsyncIOMotorCollection
+     permissions: AsyncIOMotorCollection
.

这是一个差异,用于显示这将添加的内容。


这些是我对注释的优缺点

pros

cons


希望你能帮我解决这个问题, 祝大家有个愉快的一天!

ichard26 的回答(不幸的是他没有堆栈溢出帐户)


我会键入属性,以便我的 IDE 或其他工具可以对使用这些属性的代码执行更有用的检查。

假设我有这个代码:

# let's just assume this is an invalid operation
val = collections.welcome[1]

没有类型注释的 mypy 可能不会发现这个问题,或者会抱怨有效操作不是这样 因为这些属性的定义方式是如此动态,以至于它别无选择,只能为它们假设 Any

  • It requires me to import AsyncIOMotorCollection from motor.motor_asyncio and AsyncIOMotorCollection is not declared in all

这个问题可以通过 from __future__ import annotations + if typing.TYPE_CHECKING: from motor.motor_asyncio import AsyncIOMotorCollection.

解决
  • It makes the class looks way more clunky, and i've created StaticClassList to avoid writting something like this:

是的,没有办法解决这个问题,这是动态设置属性的代价。对我来说,工具值得额外的线路,但这是你的电话。


注释未来标志导致注释保留为字符串并且永远不会被评估,除非 Python 被特别要求 并添加 typing.TYPE_CHECKING 常量(它是 False 但被类型检查器假定为 True)意味着导入实际上不存在(视觉上除外) 只有 Python 3.7+ 东西