注释可反转列表的正确方法是什么?

问题描述 投票:0回答:1

注释参数以允许可以反转的列表的正确方法是什么?

mylist = [1,2,3,4,5]
flipped = reversed(mylist)


def foo(l: list[int]) -> None:
    # assuming `l` is list object which can utilize any of it's methods.
    l.append(123)
    return

foo(mylist)
foo(flipped). # error: Argument 1 to "foo" has incompatible type "reversed[int]"; expected "list[int]"  [arg-type]

我们应该包括这两种类型吗?有更好的方法来注释吗?

def foo(l: list[int] | reversed[int]) -> None:
   ...

编辑:我试图保持

foo
通用,但有人指出
l
在函数中的使用方式对问题很重要。保持问题相对抽象,
l
需要能够利用所有典型的
list
方法(
append
extend
remove
insert
等)

python python-3.x type-hinting mypy
1个回答
0
投票

注释可反转列表的正确方法是什么? [...] l 需要能够利用所有典型的列表方法(追加、扩展、删除、插入等)

常规列表注释可以很好地表示具有列表所有功能的对象。这包括可逆性。但是,您必须传递一个列表才能使其发挥作用。对

reversed
的调用可能不会返回
list
,具体取决于您正在运行的 Python。

mylist = [1, 2, 3, 4, 5]
flipped = list(reversed(mylist))  # type remains a list

def foo(l: list[int]) -> None:
    l.append(123)
    l[:] = list(reversed(l))

foo(mylist)  # fine
foo(flipped)  # also fine

另一方面。内置行为通常有与之关联的 dunder 方法。例如,可逆性具有

__reversed__
。如果您需要为实现特定行为/方法的对象指定类型提示,您可以使用
Protocol
类来完成。

from typing import Protocol, runtime_checkable, Any

@runtime_checkable
class Reversible(Protocol):
    def __reversed__(self) -> list[Any]:
        ...

def foo(l: Reversible) -> None:
    l.append(123)

    assert isinstance(l, Reversible)  # will it work?
    l[:] = list(reversed(l))

foo(mylist)  # all good
© www.soinside.com 2019 - 2024. All rights reserved.