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(...) 方法上的有效注释是 PBeginNone。这些通常用于以 I/O 操作开始或结束的 PTransform。

例如,在保存数据时,您的转换的输出类型应为 None

class SaveResults(beam.PTransform):
    def expand(self, pcoll: PCollection[str]) -> None:
        return pcoll | beam.io.WriteToBigQuery(...)

下一步

你在等什么呢?开始在你的转换中使用注释吧!

有关 Python 中类型提示的更多背景信息,请参阅:确保 Python 类型安全

最后,如果您遇到任何问题,请告知我们