给定一个类,它有一个用于初始化的helper方法:
class TrivialClass:
def __init__(self, str_arg: str):
self.string_attribute = str_arg
@classmethod
def from_int(cls, int_arg: int) -> ?:
str_arg = str(int_arg)
return cls(str_arg)
是否可以注解from_int
方法的返回类型?
我尝试了cls
和TrivialClass
,但是PyCharm将它们标记为未解析的引用,这在当时听起来是合理的。
4条答案
按热度按时间h7wcgrx31#
从Python 3.11开始,你可以使用新的
typing.Self
对象,对于旧的Python版本,你可以使用typing-extensions
project来得到相同的对象:注意,在本例中不需要注解
cls
。警告:mypy尚未发布对
Self
类型的支持;你需要等待0.991之后的下一个版本。Pyright已经支持它了。如果你不能等待Mypy的支持,那么你可以使用一个 * 泛型类型 * 来表示你将返回一个
cls
的示例:任何子类覆盖了类方法,但返回了一个 * 父类 *(
TrivialClass
或仍是祖先的子类)的示例,都将被检测为错误,因为工厂方法被定义为返回cls
类型的示例。bound
参数指定T
必须是TrivialClass
(的子类);因为在定义泛型时该类还不存在,所以需要使用一个 forward 引用(一个名为的字符串)。参见PEP 484的 * 注解示例和类方法 * 部分。
注意:这个答案的第一个版本主张使用一个前向引用,将类本身命名为返回值,但是issue 1212使得使用泛型成为可能,这是一个更好的解决方案。
从Python 3.7开始,当你用
from __future__ import annotations
启动你的模块时,你 * 可以 * 避免在注解中使用前向引用,但是在模块级别创建一个TypeVar()
对象并不是一个注解,即使在Python 3.10中也是如此,Python 3.10推迟了注解中所有类型提示的解析。ddhy6vgd2#
在Python 3.7中,可以使用
__future__.annotations
:编辑:如果不覆盖classmethod,你就不能子类化
TrivialClass
,但是如果你不需要这个,那么我认为它比前向引用更简洁。gv8xihay3#
注解返回类型的一个简单方法是使用字符串作为类方法返回值的注解:
这传递了mypy 0.560,并且没有来自python的错误:
68bkxrlz4#
在Python 3.11中,有一种更好的方法,可以使用新的Self类型来实现这一点:
这对于子类也同样适用。
IDE显示返回类型
TrivialSubClass
,而不是TrivialClass
。这在PEP 673中进行了说明。