为什么我应该在Python中引用“名称”和“绑定”而不是“变量”和“赋值”? 我知道这个问题有点笼统,但我真的很想知道:)
答案 0 :(得分:17)
在C和C ++中,变量是命名的内存位置。变量的值是存储在该位置的值。分配给变量并修改该值。所以变量是内存位置,而不是它的名称。
在Python中,变量是用于引用对象的名称。变量的值是该对象。到目前为止听起来像是一回事。但是分配给变量并且不修改对象本身,而是改变变量引用的对象。所以变量是名称,而不是对象。
出于这个原因,如果你在抽象地考虑Python的属性,或者如果你一次讨论多种语言,那么对这两个不同的东西使用不同的名称是有用的。为了保持正确,你可以避免在Python中讨论变量,并将赋值运算符的作用称为“绑定”而不是“赋值”。
请注意The Python grammar将“作业”称为一种陈述,而非“约束”。至少有一些Python文档calls names variables。因此,仅在Python的上下文中,它不是不正确的来做同样的事情。行话词的不同定义适用于不同的语境。
答案 1 :(得分:4)
例如,在C中,变量是由特定名称标识的内存中的位置。例如,int i;
表示存在由i
标识的4字节(通常)变量。无论是否为其分配值,都会分配此内存位置。当C运行i = 1000
时,它会将存储在内存位置i
中的值更改为1000。
在python中,内存位置和大小与解释器无关。 C语义中最接近“python”的python是一个值(例如1000),它作为对象存在于内存中的某个地方,附加或不附加名称。将其绑定到名称由i = 1000
发生。这告诉python创建一个值为1000的整数对象(如果它尚不存在),并绑定到名称“i”。一个对象可以很容易地绑定到多个名称,例如:
>>> a = [] # Create a new list object and bind it to the name 'a'
>>> b = a # Get the object bound to the name 'a' and bind it to the name 'b'
>>> a is b # Are the names 'a' and 'b' bound to the same object?
True
这解释了这些术语之间的区别,但只要您了解其中的差异,您使用哪个术语并不重要。除非你是迂腐的。
答案 2 :(得分:3)
我不确定名称/绑定描述是最容易理解的,例如,即使我对Python(特别是cpython)的工作方式有一定程度的准确理解,我也总是对它感到困惑。 / p>
如果您来自C背景,描述Python如何工作的最简单方法是理解Python中的所有变量确实是对象的指针,例如list
对象确实是值的指针数组。 a = b
后a
和b
都指向同一个对象。
有一些棘手的部分,这个简单的Python语义模型似乎失败了,例如使用list
扩充运算符+=
,但为此需要注意a += b
in Python 不与a = a + b
相同,但它是一种特殊的增量操作(也可以使用__iadd__
方法为用户类型定义; a += b
确实{ {1}})。
另一个要理解的重要事情是,虽然在Python中所有变量确实是指针仍然没有指针概念。换句话说,您不能将“指向变量的指针”传递给函数,以便函数可以更改变量:C ++中的内容由
定义a = a.__iadd__(b)
或C by
void increment(int &x) {
x += 1;
}
无法定义Python中的因为无法传递“变量”,所以只能传递“值”。在Python中传递通用可写位置的唯一方法是使用回调闭包。
答案 3 :(得分:0)
我想说,由于C和Python之间存在一些差异,这种区别非常重要:
Duck输入:C变量始终是给定类型的实例 - 在Python中,它不是名称所引用的类型可以更改。
浅版 - 请尝试以下操作:
>>> a = [4, 5, 6]
>>> b = a
>>> b[1] = 0
>>> a
[4, 0, 6]
>>> b = 3
>>> a
[4, 0, 6]
这是有道理的,因为a
和b
都是名称,它们花费一些时间绑定到列表实例而不是单独的变量
答案 4 :(得分:0)
如果 调试与“命名和绑定”相关的问题,请使用此术语,因为Python语言参考使用它:尽可能具体和精确,以帮助解决问题不必要的歧义。
另一方面,如果你想知道C和Python中变量之间有什么区别,那么these pictures might help。