我讨厌写两次东西,所以我想出了一个不错的方法来避免写两次东西。然而,这似乎破坏了我的类型提示:
from enum import Enum
from dataclasses import make_dataclass, field, dataclass
class DatasetNames(Enum):
test1 = "test1_string"
test2 = "test2_string"
test3 = "test3_string"
def get_path(s: str) -> str:
return s + "_path"
# the normal way to do this, but I have to type every new dataset name twice
# and there's a lot of duplicate code
@dataclass(frozen=True)
class StaticDatasetPaths:
test1 = get_path("test1_string")
test2 = get_path("test2_string")
test3 = get_path("test3_string")
# mypy recognizes that `StaticDatasetPaths` is a class
# mypy recognizes that `StaticDatasetPaths.test2` is a string
print(StaticDatasetPaths.test2) # 'test2_string_path'
# this is my way of doing it, without having to type every new dataset name twice and no duplicate code
DynamicDatasetPaths = make_dataclass(
'DynamicDatasetPaths',
[
(
name.name,
str,
field(default=get_path(name.value))
)
for name in DatasetNames
],
frozen=True
)
# mypy thinks `DynamicDatasetPaths` is a `variable` of type `type`
# mypy thinks that `DynamicDatasetPaths.test2` is an `function` of type `Unknown`
print(DynamicDatasetPaths.test2) # 'test2_string_path'
我如何让 mypy 知道 DynamicDatasetPaths 是一个属性为字符串的冻结数据类?
通常,当我遇到这种情况时,我只需要使用 acast
并告诉 mypy 正确的类型是什么,但我不知道“属性为字符串的冻结数据类”的正确类型。
(此外,如果有更好的方法来避免重复的代码,我也会很高兴听到。)
数据类用于创建实例。由于您不是实例化数据类,而是将 、 等作为类属性进行访问
test1
,test2
因此您实际上根本不需要数据类,而只需创建类path
的属性即可Enum
。由于类的所有成员都Enum
具有字符串值,因此您可以将其改为StrEnum
类,以便更轻松地进行字符串操作:如果该
get_path
功能在实际使用中成本很高,请考虑改为path
使用cached_property
。