部落格,python & typing
2020/08/21
Python SDK 的改進註解支援
在像 Python 這樣的動態型別語言中,靜態型別檢查的重要性不容置疑。型別提示允許開發人員利用強大的型別系統來
- 撰寫更好的程式碼,
- 自我記錄不明確的程式邏輯,以及
- 在像 PyCharm 這樣的 IDE 中通知智慧程式碼完成。
這就是為什麼我們很高興宣布 Beam Python SDK 的 typehints
模組即將進行改進,包括支援型別化的 PCollections 和 PTransforms 上的 Python 3 風格註解。
改進的註解
現在,您可以選擇使用類別裝飾器或內聯函數來宣告 PTransforms 上的型別提示。
例如,具有裝飾型別提示的 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 型別系統,以在管道型別檢查和執行階段型別檢查中發揮作用。
那麼這是如何運作的呢?
型別化的 PCollections
您猜對了!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 操作開始或結束的 PTransforms。
例如,在儲存資料時,您的轉換的輸出型別應為 None
。
class SaveResults(beam.PTransform):
def expand(self, pcoll: PCollection[str]) -> None:
return pcoll | beam.io.WriteToBigQuery(...)
後續步驟
您還在等什麼..開始在您的轉換上使用註解!
有關 Python 中型別提示的更多背景資訊,請參閱:確保 Python 型別安全。
最後,如果您遇到任何問題,請告知我們。