[英]How do I pass arguments to custom static type hints in Python 3?
I'm a big fan and advocate for static type hints in Python 3. I've been using them for a while with no problems.我是 Python 3 中的静态类型提示的忠实粉丝和拥护者。我已经使用它们一段时间了,没有任何问题。
I just ran into a new edge case that I can't seem to compile.我刚刚遇到了一个我似乎无法编译的新边缘案例。 What if I want to define a custom type, then define its parameters?
如果我想定义一个自定义类型,然后定义它的参数怎么办?
For example, this is common in Python 3:例如,这在 Python 3 中很常见:
from typing import List, NewType
CustomObject = NewType('CustomObject', List[int])
def f(data: List[CustomObject]):
# do something
But this won't compile:但这不会编译:
class MyContainer():
# some class definition ...
from typing import NewType
SpecialContainer = NewType('SpecialContainer', MyContainer)
def f(data: SpecialContainer[str]):
# do something
I realize that SpecialContainer
is technically a function in this case, but it shouldn't be evaluated as one in the context of a type signature.我意识到
SpecialContainer
在这种情况下在技术上是一个函数,但它不应该在类型签名的上下文中被评估为一个函数。 The second code snippet fails with TypeError: 'function' object is not subscriptable
.第二个代码片段因
TypeError: 'function' object is not subscriptable
失败。
You have to design your classes from the ground up to accept static type hints.您必须从头开始设计类以接受静态类型提示。 This didn't satisfy my original use case, since I was trying to declare special subtypes of 3rd party classes, but it compiles my code sample.
这不能满足我最初的用例,因为我试图声明 3rd 方类的特殊子类型,但它编译了我的代码示例。
from typing import Generic, TypeVar, Sequence, List
# Declare your own accepted types for your container, required
T = TypeVar('T', int, str, float)
# The custom container has be designed to accept types hints
class MyContainer(Sequence[T]):
# some class definition ...
# Now, you can make a special container type
# Note that Sequence is a generic of List, and T is a generic of str, as defined above
SpecialContainer = TypeVar('SpecialContainer', MyContainer[List[str]])
# And this compiles
def f(data: SpecialContainer):
# do something
My original intention was to create a type hint that explained how a function, f()
, took a pd.DataFrame
object that was indexed by integers and whose cells were all strings.我的初衷是创建一个类型提示,解释函数
f()
如何pd.DataFrame
对象,该对象由整数索引并且其单元格都是字符串。 Using the above answer, I came up with a contrived way of expressing this.使用上面的答案,我想出了一种人为的表达方式。
from typing import Mapping, TypeVar, NewType, NamedTuple
from pandas import pd
# Create custom types, required even if redundant
Index = TypeVar('Index')
Row = TypeVar('Row')
# Create a child class of pd.DataFrame that includes a type signature
# Note that Mapping is a generic for a key-value store
class pdDataFrame(pd.DataFrame, Mapping[Index, Row]):
pass
# Now, this compiles, and explains what my special pd.DataFrame does
pdStringDataFrame = NewType('pdDataFrame', pdDataFrame[int, NamedTuple[str]])
# And this compiles
def f(data: pdStringDataFrame):
pass
If you are writing a custom class that resembles a container generic like Sequence
, Mapping
, or Any
, then go for it.如果您正在编写一个类似于容器泛型(如
Sequence
、 Mapping
或Any
的自定义类,那么就去做吧。 It is free to add the type variable to your class definition.可以自由地将类型变量添加到您的类定义中。
If you are trying to notate a specific usage of a 3rd party class that doesn't implement type hints:如果您尝试标注未实现类型提示的 3rd 方类的特定用法:
MyOrderedDictType = NewType('MyOrderedDictType', Dict[str, float])
MyOrderedDictType = NewType('MyOrderedDictType', Dict[str, float])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.