首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解python的名称绑定

理解python的名称绑定
EN

Stack Overflow用户
提问于 2015-01-30 02:53:54
回答 2查看 5K关注 0票数 10

我试图为自己澄清Python为变量“赋值”的规则。

下面的Python和C++之间的比较有效吗?

  1. 在C/C++中,语句int a=7意味着将内存分配给一个名为a的整数变量( =符号的上的数量),然后将值7存储在该变量中。
  2. 在Python中,语句a=7意味着首先创建一个值为7的无名整数对象(=右侧上的数量),并将其存储在内存中的某个地方。然后将名称a绑定到此对象。

下面的C++和Python程序的输出似乎证实了这一点,但我希望得到一些反馈,无论我是否正确。

C++为ab生成不同的内存位置,而ab似乎引用了Python中的相同位置(根据id()函数的输出)

C++代码

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main(void)
{
  int a = 7;
  int b = a; 
  cout << &a <<  "  " << &b << endl; // a and b point to different locations in memory
  return 0;
}

输出:0x7ff843ecb8 0x7ff843ecbc

Python:代码

代码语言:javascript
复制
a = 7
b = a
print id(a), ' ' , id(b) # a and b seem to refer to the same location

产出: 23093448 23093448

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-30 02:57:53

是的,你基本上是对的。在Python中,变量名可以被看作是对值的绑定。当人们真正开始摸索(深入理解) Python时,这是人们倾向于体验的"a ha“时刻之一。

在Python中为变量名称分配使名称绑定到与当前绑定的值不同的值(如果它确实已经绑定),而不是更改它当前绑定到的值:

代码语言:javascript
复制
a = 7   # Create 7, bind a to it.
        #     a -> 7

b = a   # Bind b to the thing a is currently bound to.
        #     a
        #      \
        #       *-> 7
        #      /
        #     b

a = 42  # Create 42, bind a to it, b still bound to 7.
        #     a -> 42
        #     b -> 7

我说的是“创建”,但这并不一定是这样的--如果某个值已经存在于某个地方,它可能会被重复使用。

在底层数据不可变(不能更改)的情况下,这通常会使Python看起来与其他语言的行为方式相同(想到C和C++ )。这是因为不能更改7 (名称绑定到的实际对象)。

但是,对于可变数据(与在C中使用指针或在C++中使用引用一样),人们有时会感到惊讶,因为他们没有意识到它背后的值是共享的:

代码语言:javascript
复制
>>> a = [1,2,3]     # a -> [1,2,3]
>>> print(a)
[1, 2, 3]

>>> b = a           # a,b -> [1,2,3]
>>> print(b)
[1, 2, 3]

>>> a[1] = 42       # a,b -> [1,42,3]
>>> print(a) ; print(b)
[1, 42, 3]
[1, 42, 3]

您需要理解a[1] = 42a = [1, 42, 3]不同。后者是一个赋值,它将导致a被重新绑定到另一个对象,因此独立于b

前者只是简单地改变了ab都绑定到的可变数据,这就是为什么两者都会受到影响的原因。

有一些方法可以获得可变值的独立副本,例如:

代码语言:javascript
复制
b = a[:]
b = [item for item in a]
b = list(a)

这些将工作到一个级别(b = a可以被认为是工作到零级别),这意味着如果a列表包含其他可变的东西,这些内容仍将在ab之间共享。

代码语言:javascript
复制
>>> a = [1, [2, 3, 4], 5]
>>> b = a[:]
>>> a[0] = 8             # This is independent.
>>> a[1][1] = 9          # This is still shared.
>>> print(a) ; print(b)  # Shared bit will 'leak' between a and b.
[8, [2, 9, 4], 5]
[1, [2, 9, 4], 5]

对于一个真正独立的副本,您可以使用deepcopy,它将按照需要将两个对象分解为多个级别。

票数 11
EN

Stack Overflow用户

发布于 2015-01-30 03:04:24

在示例代码中,由于"int“是C++中的内置类型,因此运算符"=”不能重载,但是"=“并不总是创建新对象,它们也可以引用同一个对象。python对象模块有点像Java,大部分对象是引用而不是副本。

您也可以尝试这样做:

代码语言:javascript
复制
a = 7
b = 7
print id(a), ' ' , id(b) 

它输出相同的结果,因为python将同时发现a和b指向相同的const变量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28228461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档