我在Python中工作。我有以下功能:
def f(list_value: list):
a = numpy.zeros(5)
b = numpy.zeros(4)
list_value.append(a)
list_value.append(b)
我使用它如下:
list_value[]
f(list_value)
a = list_value[0]
b = list_value[1]
我的问题是:使用a
和b
安全吗?
如果用C语言编写了与此代码等效的代码,那么它将是不安全的,因为a
和b
将是指向f
函数堆栈上的内存的指针,并且使用它们将是不安全的,因为该内存的内容将更改。但我现在在Python中,我不知道Python是否提供了一些机制来防止这种情况,或者即使在Python中也是不安全的。
1条答案
按热度按时间u5rb5r591#
Python主要是用C(cpython版本)编写的,而不是C++。
numpy
也有很多底层C代码。但是Python程序员通常从Python对象和引用(“指针”)的Angular 来思考,而不尝试定义底层的C或机器级等价物。一切事物都是对象,并存储在内存的“某处”。只要有一个“参考”的对象,如果percists。当引用计数下降到0时,它是垃圾收集的候选对象。因此,关键的思想是“什么创建了一个对象”,以及“什么包含了对它的引用”区分“可变”对象(其值或属性可以更改)和“不可变”对象也很重要。
变量只包含引用。变量的标识由什么是引用来确定。变量是通过赋值创建的。
密码:
list_value
是指向“空”列表的变量。列表是一个对象类,可以“存储”对其他对象的引用。该存储可能是C指针数组。它也有“增长”的空间,所以将对象“附加”到列表中是有效的。但这些都是实施细节。我们讨论的是一个包含对象的列表,尽管在细节上,列表的数组只有指针,而实际的对象存储在内存中的其他地方(这会让那些试图获得列表的“内存占用”的人感到困惑,因为他们天真地使用了sys.getsizeof
。下一行调用你的函数,传递给它一个对你刚刚创建的列表的引用。
函数'locally'创建2个numpy数组(也是对象)。它们被变量'a'和'b'本地引用,但是使用append,数组被“放置”在列表中。
通常函数会返回一些东西,比如
return list_value
。但是这里的返回值是None
,而list_value
仍然是可访问的,因为它只是通过引用传递的,并且是可变的。返回时,函数局部变量消失,但数组仍然作为列表的元素“存在”。
因此可以通过各种方式访问它们。
list_value
没有指示它们最初被分配给局部变量'a'和'b'。在这个意义上,列表中的数组是“无名的”。但是我们可以对这些数组做任何与它们的shape
和dtype
一致的事情。