python中的可变对象、副本和引用:如何检测问题?

python中的可变对象、副本和引用:如何检测问题?,python,reference,pylint,Python,Reference,Pylint,请告诉我我写的是否正确,如果你能在最后回答我的问题,我很高兴: 在python中分配给列表的变量是“引用”是正确的吗?这同样适用于其他可变对象(如dict,但不适用于元组) 给予 对于按值赋值而不是按引用赋值,我必须使用deepcopy(from copy) 对我来说,问题是很容易引入bug而不注意这一点!所以我声明如下 问题:是否有任何静态分析工具(如pylint或类似工具)可以对b=a或app(a,5)等行发出警告,告知我可能正在更改可变对象(列表、字典) 谢谢我阅读了标题为“和一些”的评论

请告诉我我写的是否正确,如果你能在最后回答我的问题,我很高兴:

在python中分配给列表的变量是“引用”是正确的吗?这同样适用于其他可变对象(如dict,但不适用于元组)

给予

对于按值赋值而不是按引用赋值,我必须使用
deepcopy
(from copy)

对我来说,问题是很容易引入bug而不注意这一点!所以我声明如下

问题:是否有任何静态分析工具(如pylint或类似工具)可以对
b=a
app(a,5)
等行发出警告,告知我可能正在更改可变对象(列表、字典)


谢谢

我阅读了标题为“和一些”的评论中的问题链接。我相信一般的Python赋值和参数传递在技术上是按值传递的。但是,Python中的每个赋值都会自动触发对象引用的创建。当您将
a
分配给
b
并将
a
作为参数传递给函数时,两行代码都会触发对对象
a
的引用的创建。然后将引用作为值传递给函数和
b

不幸的是,我不知道任何静态分析工具来警告您这些规则。我承认它们令人困惑,但我知道的唯一解决办法是阅读文档并尝试使用简单的代码片段测试概念。您的代码是一个很好的示例,您可以从中推断Python的“规则”和潜在问题

Python文档中的一节说明:

“…在Python中,参数是通过赋值传递的。由于赋值只创建对对象的引用…”

此外,根据对"基本法"的答复,

如果将一个可变对象传递给一个方法,该方法将获得对该对象的引用,您可以随心所欲地对其进行变异,但如果您在该方法中重新绑定该引用,外部范围将对此一无所知,并且在您完成后,外部引用仍将指向原始对象

在您的代码中,
l+=e
看起来像是方法中的“重新绑定”,不应该修改
a
。然而,可以推断Python处理
+=[e]
类似于
.append(e)
。 有人指出,“重新绑定”传递了范围外参数的函数变量不应影响传递的对象;尽管如此,
a
还是被
l+=[e]
修改了。因此,可以推断Python没有将
+=[]
视为重新绑定。我鼓励其他人也通过评论添加链接,以防出现新信息或更正


注意:
在变量上使用Python
id()
函数可能会有所帮助。它显示了Python在对象的整个“生命周期”中为标识对象而指定的整数。不幸的是,我不知道“一生”的确切定义。您最好询问他人或阅读文档:

据我所知不是这样,但一旦您习惯了这些规则,这些规则就相当简单,因此当您编写更多代码时,您不应该再犯此类错误。看看这是否有帮助:stackoverflow中的这个线程非常好:Python与其他语言不同,因此最好进行调整;例如,这不是C/C++中常用的技巧。嗨,你想链接,但却链接了这个页面吗?@Violapterin是的,我链接了。刚刚修好了。谢谢
 a = [1,2,3]
 b = a
 def app(l,e):
     l += [ e ]

 app(a,5)
 print b
 [1,2,3,5]