簡體   English   中英

可調用類的 Python 類型

[英]Python Typing for a Callable Class

我有類似的東西

class Class1(Class2):
    def __init__(
        self,
        use_class = Class3
        ...
    ):
         do something

所以Class1繼承自Class2並且需要一個默認設置為Class3的參數use_class Class3接受floats和/或strings作為輸入。 但是可以使用其他類來代替Class3 它們還接受floats和/或strings作為輸入。 但是,它們都必須從同一個Class4繼承。 此外,作為use_class有效輸入的每個類都不會返回任何內容。 所以我對打字的猜測是

class Class1(Class2):
    def __init__(
        self,
        use_class: Callable[[Union[float, str]], None] = Class3
        ...
    ):
         do something

但這並沒有包含這樣一個事實,即作為use_class給出的類必須從Class4繼承才能運行代碼。 我在這里錯過了什么嗎? 我希望這個問題有意義,非常感謝任何幫助或指示。

我們可以做其中任何一個,但不能同時做。

為了要求它是 Class4 的子類,我們將Type用於標准的名義類型:

IsClass4 = Type[Class4]

並且要求值本身是一個可調用的接受某些輸入,可以通過您建議的Callable或簡單的Protocol結構類型來處理:

class MostlyWorks(Protocol):
    def __call__(self, value: float | str) -> Class4:
        ...

理想情況下,我們希望通過交集類型來實現這兩者:

WhatWeWant = IsClass4 & AcceptsFloatsStrings

他們正在研究 PEP,但這需要一些時間。

對此有兩個想法:Python 類型檢查器通常非常松散甚至有問題,並且注釋沒有絕對規范的含義。 它們旨在捕捉現有代碼庫中的愚蠢錯誤,並使代碼更具自我記錄性。

這就是為什么我建議不要在注釋兔子洞中走得太深。

第二個想法:想象類型檢查器是一個相當昏暗的同事,如果你可以在不使用高級技術的情況下向類型檢查器解釋它,你的代碼將是清晰易讀的。

在這里,您混合了名義類型、結構類型,並且您需要一個Type[...]實例。 這是棘手的事情。

例如,假設您希望use_classClass4的子類,因此您可以在其上調用類方法。

如果我們不需要這是一個class怎么辦? 如果它只是一個看起來像一個普通的舊 Python 對象怎么辦:

class FakeClass(Protocol):
    def __call__(self, value: float | str) -> Class4:
        ...

    def works_like_classmethod(self, woah: Class77) -> str:
        ...

這讓我們回到了一個相當標准的模式,並且明確地列出了你的代碼將如何處理這件事。

暫無
暫無

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

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