[英]Provide OrderedSet[int] like types using stub file without modifying ordered-set library
我為有序集庫提供了類型提示。 問題是盡管我在ordered_set.pyi
文件中有以下幾行:
from typing import MutableSet, TypeVar, Sequence
T = TypeVar('T')
class OrderedSet(MutableSet[T], Sequence[T]):
...
我不能寫:
IntOrderedSet = OrderedSet[int]
在我的代碼中,Python提出:
TypeError: 'ABCMeta' object is not subscriptable
它發生的原因是在ordered_set.py
OrderedSet
定義為:
from collections.abc import MutableSet, Sequence
class OrderedSet(MutableSet, Sequence):
...
我做了一個帶有提交的PR,它改變了OrderedSet
類來繼承輸入類 ,但是ordered-set
所有者拒絕接受它,因為他說:
在代碼中導入鍵入會為代碼添加安裝時依賴性和運行時成本。 ordered_set作為單個模塊獲得了6年沒有依賴關系。 有人可以決定他們不想與setuptools做任何事情,只是在他們的PYTHONPATH上刪除ordered_set,它仍然可以工作。 我不想失去那種類型。
有沒有辦法,在不修改庫ordered_set.py
文件的情況下支持OrderedSet[int]
類型?
我所知道的唯一解決方法是定義任何自定義類型別名,使它們僅在類型檢查時存在,而不是在運行時存在。
為此,您需要:
if typing.TYPE_CHECKING:
blocks,則在里面定義任何類型的別名。 typing.TYPE_CHECKING
塊在運行時始終為false,並通過類型檢查器視為true。 from __future__ import annotations
,這會自動執行此操作。 也就是說,避免必須首先評估類型提示。 例如,在您的特定設置中,您可以在某處為OrderedSet庫提供存根,然后將代碼編寫為如下所示(假設Python 3.7+):
from __future__ import annotations
from typing import TYPE_CHECKING
from ordered_set import OrderedSet
# Basically equivalent to `if False`
if TYPE_CHECKING:
IntOrderedSet = OrderedSet[Int]
def expects_int_ordered_set(x: IntOrderedSet) -> None:
# blah
some_ordered_set: IntOrderedSet = OrderedSet()
或者,如果您使用的是Python 3.6或更低版本:
from typing import TYPE_CHECKING
from ordered_set import OrderedSet
if TYPE_CHECKING:
IntOrderedSet = OrderedSet[Int]
def expects_int_ordered_set(x: 'IntOrderedSet') -> None:
# blah
some_ordered_set: 'IntOrderedSet' = OrderedSet()
如果你可以稍微說謊,我們可以省去字符串的東西,並在類型檢查時間和運行時定義IntOrderedSet
略有不同。 例如:
from typing import TYPE_CHECKING
from ordered_set import OrderedSet
if TYPE_CHECKING:
IntOrderedSet = OrderedSet[Int]
else:
IntOrderedSet = OrderedSet
def expects_int_ordered_set(x: IntOrderedSet) -> None:
# blah
some_ordered_set = IntOrderedSet()
確保在你這樣做時要小心 - 類型檢查器不會檢查'else'塊中的任何內容/不會檢查以確保你所做的任何事情與if TYPE_CHECKING
中的內容if TYPE_CHECKING
塊。
最終的解決方案是首先不要定義IntOrderedSet
類型。 這讓我們跳過hack 1而只需要使用hack 2(這不是一個黑客攻擊 - 它將在幾年內成為Python中的默認行為)。
例如,我們可以這樣做:
from __future__ import annotations
from ordered_set import OrderedSet
def expects_int_ordered_set(x: OrderedSet[int]) -> None:
# blah
some_ordered_set: OrderedSet[int] = OrderedSet()
根據上下文,可能是我甚至不需要為最后一個變量聲明添加注釋。 在這里,我們這樣做,但如果我們在函數內部定義該變量,那么像mypy這樣的類型檢查器會根據我們最終使用該變量的方式自動推斷出正確的類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.