簡體   English   中英

如何鍵入一個可以接受列表或元組的列表或元組的函數?

[英]How to type a function that can take a list or tuple of a list or tuple?

我正在嘗試定義一個函數,該函數可以采用對象容器的容器,並且我不在乎容器是元組還是列表。

(我知道我可以解決實現這個的麻煩,但我不想,我仍然不確定這是否能解決我的問題。)

所以,我有以下代碼:

from typing import Any, Union, List, Tuple

# (list or tuple) of Any
AnyBucket = Union[List[Any], Tuple[Any, ...]]
# should be (list or tuple) of (lists or tuples) of Any
AnyBuckets = Union[List[AnyBucket], Tuple[AnyBucket, ...]]

def takes_any_buckets(inpt: AnyBuckets) -> None:
    print(inpt[0][0])

input_value: List[List[Any]] = [[1], [2]]

# Argument 1 to "takes_any_buckets" has incompatible type "List[List[Any]]";
# expected "Union[List[Union[List[Any], Tuple[Any, ...]]], Tuple[Union[List[Any], Tuple[Any, ...]], ...]]"
takes_any_buckets(input_value)

我有兩個問題:

  1. 為什么 Mypy 為此拋出錯誤?
  2. 我該怎么做才能獲得我想要的功能(沒有出現 Mypy 錯誤)?

(我不想只用# type: ignore禁用錯誤,我想定義一個可以工作的類型。)

我對 (1) 的猜測是它與List s is invariant 有關,但是對於這個復雜的示例,我無法弄清楚如何。

除了可能實現前面提到的麻煩之外,我對 (2) 沒有任何想法,這將使我擺脫Union s,我懷疑這可能是問題的一部分。

  1. 它確實與列表的不變性有關。 當前版本的 Mypy 會告訴你這一點; 如果您在當前版本中運行您的代碼,您會收到以下注釋以及錯誤:
main.py:14: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
main.py:14: note: Consider using "Sequence" instead, which is covariant

列表不變意味着A類型的事物列表是B類型事物列表的子類型,當且僅當A等於B 這意味着即使 A 是B的子類型List[A]也不是List[B]的子類型。 (請參閱此處,了解不變性以及 mypy 為何將列表視為不變性的原因: https ://mypy.readthedocs.io/en/stable/generics.html#variance-of-generic-types)。

所以List[List[Any]]不是List[AnyBucket]的子類型,盡管List[Any]AnyBucket的子類型,所以input_value沒有與AnyBuckets兼容的類型。 因此錯誤。

  1. 正如 Mypy 和 ShadowRanger 都在上面推薦的那樣,您可能應該使用Sequence ,這是一種協變類型,它涵蓋了可以被索引的可迭代對象(第一次近似——對於一個集合來說,還有一些其他的事情需要為真,才能成為一個順序)。 你需要從 collections.abc 導入它; 見這里: https : //docs.python.org/3/library/collections.abc.html#collections.abc.Sequence

我說“可能”是因為這完全取決於您要鍵入的函數對集合的作用。 例如,如果您所做的只是遍歷集合(一次),那么您想要使用Iterable ,這是一種更通用的類型。

使用Sequence東西的一個優點是,如果有任何其他類型的對象漂浮在那里——也許是用戶定義的對象——可以完成你想要的工作,它們將是你函數的有效輸入(只要它們已注冊為Sequences )。 一般來說,如果您可以使用結構類型(這是 Python 方式的鴨子類型的靜態類型版本等價),那就太好了。

暫無
暫無

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

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