首页 > 解决方案 > 如何在 python 中模仿 C# out 关键字功能来传递多个值

问题描述

我在这里想要实现的是更改传递给函数的名称的值,就像在 C# 中一样,可以传递一个变量,然后对它所做的任何更改即使在执行后仍然存在。我正在阅读名称绑定和 AFAIK,如果将名称传递给函数,则该函数会在其本地命名空间中创建一个名称,该名称绑定到通过引用传递的对象(python 中的所有内容都是一个对象)。由于我正在使用列表,因此我想到了一种解决方法,即清除列表,然后用另一个列表(通过可变对象)扩展它。

示例

def function(array):
    #initial length 
    length = len(array)
    #A bunch of code
    #At this point of execution, list length should have changed greatly
    array = array[length:] 
    #my workaround: temp = array[:length] ; array.clear() ; array.extend(temp)
    return something_else
#Before execution list = [1,2,3]
function(var) # inside function, list = [4,5,6]
#After execution list = [1,2,3,4,5,6] #because i use list.append(x)

笔记:

如果实际上不可能,有什么方法可以模仿这种效果。

标签: pythonpython-3.x

解决方案


不要编写改变参数的函数;惯用的 Python 基本上从不这样做,编写这样做的代码只是自找麻烦。C# 通过要求函数和调用者明确确认out语义来保持这种可管理性;使用 Python,就像使用 C++ 一样,它在调用方是不可见的,而且很多人可能没有意识到会发生突变。

只需根据需要复制以避免修改调用者的值,并使用多个返回来返回您需要作为 a 返回的所有内容tuple(这在 Python 中是微不足道的;甚至 C#在 C# 7+ 中也为此目的鼓励值元组):

def function(inarray):
    array = inarray[:]  # Shallow copy input array

    # Do stuff modifying array and computing something_else

    # Return both
    return something_else, array

var = [...]  # Some initial value of var
something, var = function(var)  # Call and unpack result

要按照描述解决您的问题,即使它通常是一个糟糕的解决方案,也不需要您的解决方法;您可以del切片,而不仅仅是读取和写入它们,而不是:

def function(array):
    #initial length 
    length = len(array)
    #A bunch of code
    #At this point of execution, list length should have changed greatly
    array = array[length:]
    return something_else

你会这样做:

def function(array):
    #initial length 
    length = len(array)
    #A bunch of code
    #At this point of execution, list length should have changed greatly
    del array[:length]  # Deletes all entries that existed when function was entered
    return something_else

它就地修改array,删除了第一个length项目。


推荐阅读