使用 PEP 484 和 585 中指定的类型提示语法,是否有任何方法可以指示函数的参数应该是由函数修改的可变引用?
例如,C# 有
ref
参数,因此在Python,有等效的吗?例如
>>> 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))
不,Python 中没有办法用类型提示来指示函数参数应该是由函数修改的可变引用。
在 Python 中,列表等参数是通过赋值传递的。但是,重要的是要理解这不是按值传递,而是按对象引用传递。
这意味着当你将一个列表传递给一个函数时,函数会收到对原始列表对象的引用。如果函数修改了列表,修改将在原始列表对象上进行。然而,如果函数将新值赋给参数名称本身,则只会影响函数的局部作用域。
在你的示例中,函数
foo
确实修改了原始列表
a
。这是因为
append
方法修改了列表对象本身。
类型提示
List[int]
已经表明参数应该是一个整数列表。没有办法进一步指定列表应该由函数修改。
Mutable
的概念在类型提示中不存在,因为 Python 中的可变性与变量本身无关,而与变量引用的对象的类型有关。
定义函数意图(包括哪些参数可能被修改)的最佳方法是使用文档字符串。
例如:
def bar(sandwich: list[str], fridge: list[str]) -> None:
"""从冰箱中随机选择 3 个项目,并将它们添加到三明治中。
Args:
sandwich: 将添加项目的列表。
fridge: 可选项目的列表。
"""
sandwich.extend(random.sample(fridge, k=3))
这种方法使得开发人员能够清楚地理解
sandwich
列表的预期用法和修改。