【问题标题】:Python Typing: Should i add type annotations for __slots__ in my class?Python 打字:我应该在课堂上为 __slots__ 添加类型注释吗?
【发布时间】:2021-08-21 02:04:45
【问题描述】:

我有一个关于在 python 中打字的问题。

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


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

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 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()))]
            )

    ...

快速提示:这个抽象类被多个类使用,并且 __init__ 方法被减少到必要的最小值,这是两个...的原因p>


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

. 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

  • 不清楚每个插槽都是AsyncIOMotorCollection“显式优于隐式”的实例。(Python 之禅)
  • 它允许 ide 检测属性(没有其他注释,但这很重要吗?)

cons

  • 它需要我从motor.motor_asyncio 导入AsyncIOMotorCollection 并且AsyncIOMotorCollection 没有在__all__ 中声明

  • 它让这个类看起来更笨重,我创建了StaticClassList 以避免写这样的东西:

        # <Collections>
        plugins: AsyncIOMotorCollection = database.axiol["Plugins"]
        prefixes: AsyncIOMotorCollection = database.axiol["Prefixes"]
        reaction_roles: AsyncIOMotorCollection = database.axiol["Reaction Roles"]
        ...
    

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

【问题讨论】:

  • 欢迎来到 Stack Overflow。这种事情在这里被认为是题外话,因为它是主观的。就我个人而言,我认为一旦我们决定同时使用__slots__ 和类型注释,我们就已经离开了simple is better than complex; complex is better than complicated 的世界。如果您想要一种在编译时检查类型的语言,请使用一种。甚至存在可以进行类型推断且不需要清单输入的方法。
  • 谢谢,但是为了在编译时检查类型而不是为了帮助理解所涉及的类型而输入模块,对吧?几乎 Python 是我的主要语言,不会在其他语言中制作这个项目 ^^.
  • 就像我说的,这是一个见仁见智的问题,这正是我们不喜欢这样的问题的原因。您可能在 论坛 上运气更好,例如在 Reddit 或 Quora 上。
  • 我对此深表歉意,虽然我的第一个问题已经做好了一切,但似乎我错过了重要的一点。会记下我的未来问题,希望不要再犯这个错误!

标签: python python-typing


【解决方案1】:

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


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

假设我有这个代码:

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

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

  • 它需要我从 motor.motor_asyncio 导入 AsyncIOMotorCollection 并且 AsyncIOMotorCollection 没有全部声明

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

  • 它使类看起来更笨重,我创建了 StaticClassList 以避免写这样的东西:

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


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

【讨论】:

    猜你喜欢
    • 2013-11-15
    • 2018-07-05
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2011-01-25
    • 1970-01-01
    相关资源
    最近更新 更多