简体   繁体   English

如何将参数传递给 Python 3 中的自定义静态类型提示?

[英]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失败。

Compiling My Code Sample编译我的代码示例

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

Subtyping a 3rd Party Class对第 3 方类进行子类型化

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

Was it worth it?它值得吗?

  • If you are writing a custom class that resembles a container generic like Sequence , Mapping , or Any , then go for it.如果您正在编写一个类似于容器泛型(如SequenceMappingAny的自定义类,那么就去做吧。 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 方类的特定用法:

    • Try using an existing type variable to get your point across, eg MyOrderedDictType = NewType('MyOrderedDictType', Dict[str, float])尝试使用现有的类型变量来表达您的观点,例如MyOrderedDictType = NewType('MyOrderedDictType', Dict[str, float])
    • If that doesn't work, you'll have to clutter your namespace with trivial child classes and type variables to get the type hint to compile.如果这不起作用,您将不得不用琐碎的子类和类型变量来弄乱您的命名空间,以获取要编译的类型提示。 Better to use a docstring or comment to explain your situation.最好使用文档字符串或注释来解释您的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 python 3.5 类型提示:我可以检查函数参数是否匹配类型提示吗? - python 3.5 type hints: can i check if function arguments match type hints? Python 类型提示:如何做文字范围 - Python type hints: how to do a literal range 如何在 Python 中传递任意 arguments - How do I pass arbitrary arguments in Python Python,如何让自定义类型来描述更具体的类型提示? - In Python, how to make a custom type to describe a more specific type hints? 如果 Python 运行时忽略类型提示,为什么会出现 TypeError? - If the Python runtime ignores type hints, why do I get a TypeError? 如何在 Visual Studio Code 中正确突出显示 python 的类型提示? - How do I properly highlight type hints for python in Visual Studio Code? 如何在 python 中为带有 boto3 对象的函数添加类型提示? - How do I add type hints to fuctions with boto3 objects in python? 如何为 argparse 参数提供类型提示? - How to provide type hints for argparse arguments? 如何“投射” Python类型提示 - How to “cast” python type hints 输入提示和@singledispatch:如何以可扩展的方式包含`Union [...]`? - Type hints and @singledispatch: how do I include `Union[...]` in an extensible way?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM