如何定义自定义的无特殊形式类型
我需要以下的行为:
NoOp = ... # don't know how to define this
def foo(bar: NoOp[int]) -> int:
return bar + 1
foo(1)
我希望Mypy像bar
完全一样,就像我只是将其注释为bar:int
。我还需要它与int
本身不同,以便编写代码,以检查是否用Eg noop [str]
vs Just str
noop >。只是Mypy应该对待他们。
我试图与 newtype
得到类似的东西,但是由于它将结果定义视为一个子类,因此无法用于我的目的,而我必须使用它的方式也创建了非常非常的代码很难阅读。
I need something that behaves as follows:
NoOp = ... # don't know how to define this
def foo(bar: NoOp[int]) -> int:
return bar + 1
foo(1)
I want mypy to treat bar
exactly as if I had simply annotated it as bar: int
. I also need it to be distinct from int
itself in order to write code that checks if something was annotated with e.g. NoOp[str]
vs just str
. It's just mypy that should treat them the same.
I tried to work with NewType
to get something similar, but since it treats the resulting definition as a subclass it didn't work for my purposes, and the way I had to use it also created code that was very hard to read.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果我正确理解,
noop [t]
和t
在运行时和类型检查器的眼中都是完全相同的类型。唯一的区别是您要编写检查注释的自定义代码,并且能够告诉t
除noop [t]
外。这是正确的吗?如果是这样,则可以查看
注释
类型,在Python 3.9中引入,并通过typing_extensions
进行了回波。它采用注释的[t,x]
的形式,其中t
是一种类型注释,x
是任意的元数据。它允许您将元数据x
与注释t
相关联,而不更改类型(IE注释[T,x]
等于<代码> t )。对于您的情况,您可以将
noop
定义为通用类型别名:然后,您可以使用
typing.get_type_hints
(替换typing
用typing_extensions
在3.9之前的版本)。注释对象将具有__元数据__
属性,该属性容纳了元数据的元组:原因是元组,因为您可以将多个值与之相关联,例如
注释[INT,“ A” ,“ B”,1.234]
。If I understand correctly,
NoOp[T]
andT
are exactly the same type both at runtime and also in the eyes of the type checker. The only difference is that you want to write custom code that inspects the annotations, and be able to tellT
apart fromNoOp[T]
. Is this correct?If so, then you could check out the
Annotated
type, introduced in Python 3.9 and backported viatyping_extensions
. It takes the form ofAnnotated[T, X]
, whereT
is a type annotation andX
is arbitrary metadata. It allows you to associate the metadataX
with annotationT
, while not changing the type (i.e.Annotated[T, X]
is equivalent toT
).For your case, you could define
NoOp
as a generic type alias:You can then inspect the annotations with
typing.get_type_hints
(replacetyping
withtyping_extensions
for versions prior to 3.9). The annotation object will have a__metadata__
attribute, which holds a tuple of the metadata:The reason it's a tuple is because you could associate multiple values with it, e.g.
Annotated[int, "a", "b", 1.234]
.有些疑问,因为我不确定我会得到您的用户酶 - 对不起,如果这不是您的需求。
另一方面,如果您想制作
包装器
以便在f
中进行实例检查,则可以做类似的操作需要小心,因为您最终会出现一个非交易
__添加__
(不一定是错误的,但要注意的是什么)。With some doubts because I am not sure I got your usecase -- sorry if this is not what you need.
If on the other hand you want to make
Wrapper
to behave functorially so that you don't need to do instance checks withinf
, you could do something likebut you'd need to be careful because you'll end up with a non-commutative
__add__
(not necessarily wrong, but something to be aware of).