[英]Avoid PyCharm Type-Warning when using typing.NewType
After slowly getting the hang of typing in collaboration with PyCharm, I find myself using the package a lot.在与 PyCharm 合作慢慢掌握打字的窍门后,我发现自己经常使用 package。 I like its flexibility and how it can be adapted to almost any use case.我喜欢它的灵活性以及它如何适应几乎任何用例。
While playing with the package (and also because it'd be really useful) I thought about creating a "wrapper-type" for certain str
ids I get from a database and use as dictionary keys throughout the project.在使用 package 时(也因为它非常有用),我考虑为我从数据库中获取的某些str
id 创建一个“包装器类型”,并在整个项目中用作字典键。
That way, if a function was passing a dictionary using ids gotten directly from the database as keys, the type hints would not just hint at the required type, but also provide some information on the dataflow and key structures, if not just one, but two or more database ids were used, to make up a dictionary key.这样,如果 function 使用直接从数据库中获取的 id 作为键传递字典,则类型提示不仅会提示所需的类型,还会提供有关数据流和键结构的一些信息,如果不仅仅是一个,而是使用了两个或多个数据库 ID 来组成字典键。
I thought the facility of choice would be NewType
, since it actually creates a new type with a name that can be shown in PyCharms tooltip (Unlike TypeAlias
or just PrimaryKey = str
).我认为选择的工具是NewType
,因为它实际上创建了一个新类型,其名称可以显示在 PyCharms 工具提示中(与TypeAlias
或只是PrimaryKey = str
不同)。 However, as predicted in the documentation , PyCharm's static type checker does not accept the created NewType
as str
and raises a type warning.但是,正如文档中所预测的那样,PyCharm 的 static 类型检查器不接受创建的NewType
作为str
并引发类型警告。
"Expect '{NewType xy}' got 'str' instead".
So my question: Is there any way around that?所以我的问题是:有没有办法解决这个问题?
# instead of:
some_info: Mapping[Tuple[str, str], List[Any]] = dict() # obviously works
# it'd look like this:
PrimaryKeyA = NewType('PrimaryKeyA', str)
PrimaryKeyB = NewType('PrimaryKeyB', str)
some_info: Mapping[Tuple[PrimaryKeyA, PrimaryKeyB], List[Any]] = dict()
some_info['AKey_01', 'BKey_01'] = 'example_data' # raises type warning
# I could do:
some_info[PrimaryKeyA('AKey_01'), PrimaryKeyB('BKey_01')] = 'example_data'
# But that doesn't feel more readable
In the project I'm currently involved with, this would be a giant improvement for readability since the whole thing is collecting stuff on different levels of detail, each level identified by a database primary key.在我目前参与的项目中,这将是可读性的巨大改进,因为整个事情正在收集不同详细级别的内容,每个级别都由数据库主键标识。 But if I can't get it to work with PyCharm, I don't think it'd be worth the trouble.但如果我不能让它与 PyCharm 一起工作,我认为这不值得麻烦。
The main goal of NewType
is to help detect logical errors, like not passing in a PrimaryKey
were you should. NewType
的主要目标是帮助检测逻辑错误,例如不应该传入PrimaryKey
。 so I think the best way to do it is how you showed last.所以我认为最好的方法是你最后展示的方式。
some_info[PrimaryKeyA('AKey_01'), PrimaryKeyB('BKey_01')] = 'example_data'
one thing you could do is define those strings before in the program.您可以做的一件事是在程序之前定义这些字符串。
key_1 = PrimaryKeyA('AKey_01')
key_2 = PrimaryKeyB('BKey_01')
some_info[key_1, key_2]
or take them as arguments to a function depending on the context.或根据上下文将它们作为 arguments 到 function 。 as this should work:因为这应该有效:
def foo(key_1: PrimaryKeyA, key_2: PrimaryKeyB) -> None:
some_info[key_1, key_2] = 'example_data'
since it actually creates a new type with a name因为它实际上创建了一个具有名称的新类型
lastly I just want to point out that this is actually not correct, atleast not at runtime.最后我只想指出这实际上是不正确的,至少在运行时不是。 type checkers will treat it as a new type yes, but at runtime it just returns whatever given to it.类型检查器会将其视为新类型,是的,但在运行时它只会返回给它的任何内容。
In [1]: from typing import NewType
In [2]: A = NewType("A", int)
In [3]: A("abc")
Out[3]: 'abc'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.