这是一个真正的numpy新手问题.
我有一个名为'image'的numpy数组.这样做:
image2 = image
image2[image < minval] = minval
image2[image > maxval] = maxval
Run Code Online (Sandbox Code Playgroud)
...更改"图片"的内容.
我收集的是因为Python中的变量确实是引用,所以'image2'只是引用'image'的另一种方式.所以我应该使用"image2 = np.copy(image)".精细.
但是,那么,当我这样做时,为什么不"改变":
a = 5
b = a
b = 7
Run Code Online (Sandbox Code Playgroud)
不是'b'只是提到'a'的另一种方式吗?如果是这样,为什么在这个结束时a == 7?
我想知道是否有一些心理模型使这看起来一致.因为它没有.
答案确实在于直接分配喜欢b=a
和b=7
工作的方式。 b=a
创建对也被引用的对象的新引用a
,并将该新引用与名称关联b
。然后,后续操作b=7
将删除附加到名称的引用,并与名称b
建立不同的关联b
。无论a
是不可变类型(如整数)还是可变类型(如numpy数组),这都是正确的。两种情况都不会a
被修改。
相比之下,image2[image < minval] = minval
这不是重新分配。通过使用[]
它,可以调用__setitem__
对象的method()image2
。此方法无需更改任何内容即可更改基础数据结构的某些部分image2
。
Python最基本的类型是“不可变的”。这意味着您无能为力,无法更改它们(例如,如果image2
属于不可变类型tuple
,则尝试使用[]
索引更改其元素之一将引发异常)。
结果,非常非常宽松,如果您习惯了C / C ++的思维方式,有时在查看函数或函数时可以将不可变类型视为通过值传递而将可变类型视为通过引用传递方法原型。但是,正如注释中所指出的,这并不是真正发生的事情:所有内容都是引用,但是某些引用(不可变类型)将自动按照C / C ++处理const
引用的方式进行处理。
不可变类型包括:
bool
,int
,long
,float
和complex
str
,unicode
(仅限python 2.x)和bytes
(仅限python 3.x)tuple
(但不是list
)