对于 C 程序员:C 变量是 指针,python 变量是 句柄。我认为你真的想做这样的事情,但是在 python 中:
// C code
std::vector<int> myvector;
myfunction(std::vector<int> &testvector) {
if (somearg) {
testvector.append(4)
} else {
int[] myints = {4,15,16};
testvector = std::vector<int>(myints)
}
}
因为 testvector 是一个指向对象的指针,并且您更改了它指向的对象,所以无论您走哪条路径,父级都会看到您的更改。
在 python 中,这看起来像这样:
list1 = [1,2,3]
def modfunc(mylist):
if (somearg):
mylist.append(4)
else:
mylist = [1,2,3]
虽然第一个会起作用,但第二个不会。在这种情况下, mylist 不是直接指向内存的指针;它指向对象查找表中的一个条目,然后指向真实对象。在失败的情况下,您将名称 mylist 更改为指向不同的对象,但父对象的名称仍指向原始对象。
在它工作的第一种情况下,您实际上尊重名称和对象列表以获取实际对象并直接操作它。父母和孩子的名字都指向这个对象,所以它可以工作。
那么,你是做什么的?好吧,简而言之,您不需要这样做。在 C 中,您经常需要引用,因为它将您限制为单个返回值。当然,您可以使用结构,但在 C 中这样做不是很方便。在 python 中,元组是该语言的自然组成部分。所以假设你想在 C 中做这样的事情:
int sumdefault(std::vector<int> &avector):
if len(avector) == 0:
int[] someints = {1,2,3,4,5}
avector = std::vector<int>(someints);
return sum(avector)
因此,您需要 int 返回值来返回总和。你也可能会改变一个向量,所以你需要返回一个引用。此外,返回 avector(例如,成对的)可能很危险,因为您正在本地堆栈上创建一个变量,因此返回对它的引用实际上是无效的,但按值返回可能很昂贵(并且不必要)如果avector很大,yada yada。在 python 中,您只需返回两个值:
def sumdefault(mylist=[]):
if len(mylist) == 0:
mylist = [1,2,3,4,5]
return mylist, sum(mylist)
alist = [2,3,4,5]
alist, sumalist = sumdefault(alist)
这是(afaik)处理这种模式的正确pythonic方法。你永远不会浪费时间不必要地复制列表——Python 总是传递对事物的引用。并且 Python 确实没有像 C 那样的“局部”变量:在子函数中创建的变量具有局部 name,但它位于全局堆中,所以即使我们在子函数中构造[1,2,3,4,5],当我们返回一个函数时,该内存不会消失 - 我们的本地名称将消失,但父函数现在将有一个指向它的名称,它会一直存在正如某些名称所引用的那样。