Python 区分类型别名和实际类的约定?

Python 区分类型别名和实际类的约定?,python,type-hinting,mypy,Python,Type Hinting,Mypy,键入模块允许将复杂类型签名分配给,然后可以与实际类型互换使用。这似乎有一个问题,它将类型别名与实际类混淆,即在这样的定义中 def foo(obj: MyComplexObject): ... 无法判断MyComplexObject是作为某个类实现的,还是仅仅是一个类型别名。对我来说,这似乎是一个不幸的困惑来源,尤其是当别名(重新)使用时,它与最初的定义相去甚远。这是否已被普遍接受,或者是否有某种约定可以区分类型别名和实际类?没有区分这两者的正式约定 类型别名与其他语言中的typede

键入模块允许将复杂类型签名分配给,然后可以与实际类型互换使用。这似乎有一个问题,它将类型别名与实际类混淆,即在这样的定义中

def foo(obj: MyComplexObject):
    ...

无法判断
MyComplexObject
是作为某个类实现的,还是仅仅是一个类型别名。对我来说,这似乎是一个不幸的困惑来源,尤其是当别名(重新)使用时,它与最初的定义相去甚远。这是否已被普遍接受,或者是否有某种约定可以区分类型别名和实际类?

没有区分这两者的正式约定


类型别名与其他语言中的typedef非常相似。但是,按照约定,类型别名用于复杂的类型组合,例如
Message=Union[str,MyClass1,MyClass2,OtherClass]
,在这种情况下,多次写出完整的Union会很麻烦。因此,单个名称的注释应该是:一个类型,或者是一些别名类型的组合。你必须根据名称的定义来区分它们。

我认为类型别名和常规类型在设计上是无法区分的:类型别名意味着它们是任何类型别名的精确替代品

因此,使用您的示例,如果
MyComplexObject
是实际的类还是类型别名并不一定重要:它们在运行时和静态类型检查时的行为都是等效的

而且,由于类型检查器可以立即向您提供有关是否以类型安全的方式使用
obj
的反馈,因此,混淆的机会很小:要么正确使用
obj
参数,要么立即获得反馈。(类似地,理解PEP 484语义的IDE(如Pycharm)也能理解类型别名,并能正确地自动完成/标记错误。)

还值得注意的是,在专门为其他类别名的情况下,别名和原始类在运行时实际上是不可区分的:它们都是引用相同基础类型对象的变量。(因此可以说,实际上没有什么值得混淆的:别名和原始类型都是“同一件事”。)

因此,很少有人愿意找到一个命名约定来区分类型和类型别名——实际上这并不是一个问题


也就是说,对于何时使用类型别名,存在一些隐式约定。例如,人们通常不会直接为类别名:正如Ethan所说,类型别名主要用于帮助简化在多个位置重复的大型复合类型

这意味着类型别名主要是在您可能有一堆非常难看的类型签名时使用的。然后,这就变成了一种“折衷”的事情:读者确实需要花时间查找别名的定义并将其缓存在头脑中,但一旦他们这样做了,阅读其余的代码应该会更愉快


因此,如果您仍然发现类型别名可能令人困惑,并且除非必要,否则更愿意避免使用它们,那就很好了:几乎所有其他人都是这样做的。唯一的区别在于当你从“不必要”到“必要”跨越临界点时。

Hm,这是一个非常不愉快的情况。我几乎倾向于考虑匈牙利符号,比如别名声明(<代码> MyFieldObjuts),比不必怀疑是否曾经定义过一个特定类稍微恼人。类型别名,像所有抽象一样,只有在正确完成时才能工作。他们把一件复杂的事情隐藏成一件简单的事情。从根本上说,您正试图打破抽象障碍,而且可能不应该这样做。相反,为别名指定语义上有意义的名称,并让这些名称指示理解类型。