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

标签 python python-3.x python-3.6 python-3.5 python-typing

我是 Python 3 中静态类型提示的忠实拥护者和拥护者。我已经使用它们一段时间了,没有遇到任何问题。

我刚刚遇到了一个我似乎无法编译的新边缘案例。如果我想定义一个自定义类型,然后定义它的参数怎么办?

例如,这在 Python 3 中很常见:

from typing import List, NewType
CustomObject = NewType('CustomObject', List[int])

def f(data: List[CustomObject]):
    # do something

但这不会编译:

class MyContainer():
    # some class definition ...

from typing import NewType
SpecialContainer = NewType('SpecialContainer', MyContainer)

def f(data: SpecialContainer[str]):
    # do something

我意识到 SpecialContainer 在这种情况下在技术上是一个函数,但它不应该在类型签名的上下文中被评估为一个函数。第二个代码片段因 TypeError: 'function' object is not subscriptable 而失败。

最佳答案

编译我的代码示例

您必须从头开始设计您的类以接受静态类型提示。这不满足我最初的用例,因为我试图声明第 3 方类的特殊子类型,但它编译了我的代码示例。

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

子类型化第 3 方类

我的初衷是创建一个类型提示来解释函数 f() 如何获取一个由整数索引的 pd.DataFrame 对象及其单元格都是字符串。使用上面的答案,我想出了一种人为的表达方式。

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

值得吗?

  • 如果您正在编写类似于 SequenceMappingAny 等容器泛型的自定义类,那么请使用它。可以自由地将类型变量添加到您的类定义中。

  • 如果您尝试标记未实现类型提示的第 3 方类的特定用法:

    • 尝试使用现有的类型变量来表达您的观点,例如MyOrderedDictType = NewType('MyOrderedDictType', Dict[str, float])
    • 如果这不起作用,您将不得不用琐碎的子类和类型变量来打乱您的命名空间,以获得要编译的类型提示。最好使用文档字符串或注释来解释您的情况。

关于python - 如何将参数传递给 Python 3 中的自定义静态类型提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52153879/

相关文章:

python - 为什么我的电脑上安装了3个python?

Python 并发.futures : handling exceptions in child processes

python - (s 是 "")和(s == "")能否在 Python 2.6.2 中给出不同的结果?

python - 使用 lxml.html 的 cssselect 选择 ID 属性中带有冒号的元素

python - 在 tf.keras 中正确设置 GAN 实现中的 .trainable 变量

python - 参数和签名的使用

python - “pip install minecraft”不起作用,找不到文件

python - 如何引用没有定义变量的现有类对象?

python - 在多处理或多线程应用程序中保留 cpu 时间

python - PySerial 未使用 python 3.6.4 导入。也是 3.5 或更高版本。