我有一个数据类,它的字段可能是常量,也可能是采用
Self
的函数。有一个辅助函数可以做正确的事情——如果字段包含常量,它就返回该常量。如果该字段包含函数,则使用 self
: 调用该函数
from dataclasses import dataclass
from typing import Self, Callable
@dataclass
class MyClass:
my_func_field: str | Callable[[Self], str]
def my_field(self) -> str:
if isinstance(self.my_func_field, str):
return self.my_func_field
else:
return self.my_func_field(self)
mypy 不喜欢这个(playground):
main.py:12: error: Argument 1 has incompatible type "MyClass"; expected "Self" [arg-type]
但是,如果我简化情况,使它只是一个可调用的,我就不会遇到这个问题:
from dataclasses import dataclass
from typing import Self, Callable
@dataclass
class MyClass:
my_func_field: Callable[[Self], str]
def my_field(self) -> str:
return self.my_func_field(self)
这让我感到惊讶。我假设第一个示例中的
else
分支的类型检查与第二个示例完全相同,因为在 else
分支中,my_func_field
已缩小为 Callable[[Self], str]
,其类型与第二个示例完全相同第二个例子。
我在这里缺少什么?是否可以让 mypy 接受某些内容,或者我是否必须使用
# ignore
评论?
get_instance 是一个实例方法,返回当前实例(自身)。使用 -> Self 作为返回类型告诉 mypy 该方法返回当前类类型。
create 是一个类方法,充当工厂,创建并返回 MyClass 的新实例。由于它是一个@classmethod,因此传递的是 cls 而不是 self,并且 -> Self 允许 mypy 推断它返回同一类的实例。
通过使用 Self,mypy 现在应该正确推断返回类型而不会出现错误。
输入 import Self
我的班级: def init(自身,值:int): 自我价值=价值
def get_instance(self) -> Self:
"""Instance method returning the current instance"""
return self
@classmethod
def create(cls, value: int) -> Self:
"""Factory method that creates a new instance of MyClass"""
return cls(value)