簡體   English   中英

如何為動態創建的類添加類型注釋?

[英]How can I add type-annotations to dynamically created classes?

在一個應用程序中,我有生成動態類的代碼,該類大大減少了重復代碼的數量。 但是,添加用於mypy檢查的類型提示會導致錯誤。 考慮下面的示例代碼(簡化為關注相關位):

class Mapper:

    @staticmethod
    def action() -> None:
        raise NotImplementedError('Not yet implemnented')


def magic(new_name: str) -> type:

    cls = type('%sMapper' % new_name.capitalize(), (Mapper,), {})

    def action() -> None:
        print('Hello')

    cls.action = staticmethod(action)
    return cls


MyCls = magic('My')
MyCls.action()

使用mypy進行檢查將導致以下錯誤:

dynamic_type.py:15: error: "type" has no attribute "action"
dynamic_type.py:21: error: "type" has no attribute "action"

mypy顯然無法判斷type調用的返回值是Mapper的子類,因此它抱怨說,當我給它賦值時,“類型”沒有屬性“動作”。

請注意,該代碼可以正常運行,並且可以實現預期的功能,但是mypy仍然抱怨。

有沒有辦法將cls標記為Mapper類型? 我試圖簡單地將#type # type: Mapper追加到創建類的行:

cls = type('%sMapper' % new_name.capitalize(), (Mapper,), {})  # type: Mapper

但是隨后出現以下錯誤:

dynamic_type.py:10: error: Incompatible types in assignment (expression has type "type", variable has type "Mapper")
dynamic_type.py:15: error: Cannot assign to a method
dynamic_type.py:15: error: Incompatible types in assignment (expression has type "staticmethod", variable has type "Callable[[], None]")
dynamic_type.py:16: error: Incompatible return value type (got "Mapper", expected "type")
dynamic_type.py:21: error: "type" has no attribute "action"

一種可能的解決方案基本上是:

  1. 使用預期的輸入和輸出類型鍵入您的magic函數
  2. 明智地使用Any# type: ignore ,使magic函數的內容保持動態# type: ignore

例如,類似這樣的方法將起作用:

class Mapper:
    @staticmethod
    def action() -> None:
        raise NotImplementedError('Not yet implemnented')


def magic(new_name: str) -> Mapper:

    cls = type('%sMapper' % new_name.capitalize(), (Mapper,), {})

    def action() -> None:
        print('Hello')

    cls.action = staticmethod(action)  # type: ignore
    return cls  # type: ignore


MyCls = magic('My')
MyCls.action()

保留部分代碼動態鍵入似乎有些令人反感,但在這種情況下,我認為沒有任何避免的方法:mypy(和PEP 484輸入生態系統)故意不嘗試處理超動態代碼,例如這個。

相反,您能做的最好的事情就是干凈地記錄“靜態”界面,添加單元測試,並將代碼的動態部分限制在盡可能小的區域內。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM