指示参数应该是可变引用

2024-10-04 01:35:04 发布

您现在位置:Python中文网/ 问答频道 /正文

对于PEP 484和585中指定的类型提示语法,是否有任何方法可以指示函数的参数应该是可由函数修改的可变引用

例如,C#有ref个参数,所以在Python中,是否有任何等价物?e、 g

>>> def foo(spam: "Mutable[List[int]]"):
...     spam.append(sum(spam))
...
>>> a = [1, 2, 3]
>>> foo(a)
>>> a
[1, 2, 3, 6]

或者如果不是,我如何定义这样一个类型而不使检查逻辑认为它是一个特殊的Mutable类而不是List[int]?显然,这将被用作开发人员更容易理解方法的工具,而不是用来从根本上改变程序的工具

为了清楚起见,我知道列表的定义是可变的,但我想知道是否有一种方法可以定义,例如,当发生变异时

>>> def bar(sandwich: Mutable[List[str]], fridge: List[str]):
...     sandwich.extend(random.sample(fridge, k=3))

Tags: 工具方法函数类型参数定义foodef
2条回答

默认情况下,列表被视为始终是可变的。因此,如果您想表明某些列表永远不会更改,最好使用一些只读接口或协议(如typing.Sequencetyping.Collection)来明确表示

这两种类型的语义与相应的collections.abc类型相同。我想你可以把它们看作与C#的IReadOnlyCollection大致相同

from typing import Sequence, overload

def foo(seq: Sequence[int]) -> None:
    # This type checks
    for item in seq:
        print(seq)

    # ...but this does not. Mypy reports a
    # '"Sequence[int]" has no attribute "append" error', for example
    seq.append(5)

# This type checks, since lists satisfy the Sequence protocol
foo([1, 2, 3, 4])

# Same thing with tuples
foo((1, 2, 3, 4))

class CustomSequence(Sequence[int]):
    @overload
    def __getitem__(self, i: int) -> int: ...
    @overload
    def __getitem__(self, s: slice) -> Sequence[int]: ...
    def __getitem__(self, x: Union[int, slice]) -> Union[int, Sequence[int]]:
        if isinstance(x, int):
            return 1
        else:
            return [1, 2]

    def __len__(self) -> int:
        return 1

# Or any other kind of Sequence, actually.
foo(CustomSequence())

如果您想要一个通用的可变序列,请使用MutableSequence。请注意,列表同时满足Sequence和MutableSequence协议

列表在Python中是可变的,因此不需要显式的Mutable类引用:

In [3]: from typing import List

In [7]: def foo(spam:List[int]):
   ...:     spam.append(sum(spam))
   ...:     return spam  

In [8]: a = [1,2,3]   

In [9]: foo(a)

Out[9]: [1, 2, 3, 6]

相关问题 更多 >