博客、python 和类型提示
2020/08/21
Python SDK 改进注释支持
在像 Python 这样的动态类型语言中,静态类型检查的重要性是不言而喻的。类型提示允许开发人员利用强大的类型系统来
- 编写更好的代码,
- 自我记录模糊的编程逻辑,以及
- 在 PyCharm 等 IDE 中提供智能代码补全。
这就是我们很高兴宣布即将对 Beam 的 Python SDK 的 typehints
模块进行改进的原因,包括对类型化 PCollection 和 Python 3 风格的 PTransform 注释的支持。
改进的注释
今天,您可以选择使用类装饰器或内联函数来声明 PTransform 上的类型提示。
例如,带有装饰类型提示的 PTransform 可能看起来像这样
@beam.typehints.with_input_types(int)
@beam.typehints.with_output_types(str)
class IntToStr(beam.PTransform):
def expand(self, pcoll):
return pcoll | beam.Map(lambda num: str(num))
strings = numbers | beam.ParDo(IntToStr())
相反,使用内联函数,相同的转换将看起来像这样
class IntToStr(beam.PTransform):
def expand(self, pcoll):
return pcoll | beam.Map(lambda num: str(num))
strings = numbers | beam.ParDo(IntToStr()).with_input_types(int).with_output_types(str)
这两种方法都有问题。类装饰器语法繁重,需要两行额外的代码,而内联函数提供的类型提示在相同转换的其他实例中不可重用。此外,这两种方法都不兼容 MyPy 等静态类型检查器。
然而,使用 Python 3 注释,我们可以绕过这些问题,提供一个干净且可重用的类型提示体验。我们之前的转换现在看起来像这样
class IntToStr(beam.PTransform):
def expand(self, pcoll: PCollection[int]) -> PCollection[str]:
return pcoll | beam.Map(lambda num: str(num))
strings = numbers | beam.ParDo(IntToStr())
这些类型提示将主动连接到内部 Beam 类型系统,以在管道类型检查和运行时类型检查中发挥作用。
那么它是如何工作的呢?
类型化 PCollection
你猜对了!PCollection 类继承自 typing.Generic
,允许它使用零个类型(表示为 PCollection
)或一个类型(表示为 PCollection[T]
)进行参数化。
- 具有零个类型的 PCollection 隐式转换为
PCollection[Any]
。 - 具有一个类型的 PCollection 可以具有任何嵌套类型(例如
Union[int, str]
)。
在内部,Beam 的类型系统通过删除外部 PCollection 容器来使这些注释与其他类型提示兼容。
PBegin、PDone、None
最后,除了 PCollection 之外,PTransform 的 expand(...)
方法上的有效注释是 PBegin
或 None
。这些通常用于以 I/O 操作开始或结束的 PTransform。
例如,在保存数据时,您的转换的输出类型应为 None
。
class SaveResults(beam.PTransform):
def expand(self, pcoll: PCollection[str]) -> None:
return pcoll | beam.io.WriteToBigQuery(...)
下一步
你在等什么呢?开始在你的转换中使用注释吧!
有关 Python 中类型提示的更多背景信息,请参阅:确保 Python 类型安全。
最后,如果您遇到任何问题,请告知我们。