python - 为什么变量 = 对象不像变量 = 数字那样工作

标签 python python-2.7 variables object python-3.x

这些变量赋值按我的预期工作:

>>> a = 3
>>> b = a
>>> print(a, b)
(3, 3)
>>> b=4
>>> print(a, b)
(3, 4)

但是,这些分配的行为不同:

>>> class number():
...     def __init__(self, name, number):
...         self.name = name
...         self.number = number
... 
>>> c = number("one", 1)
>>> d = c
>>> print(c.number, d.number)
(1, 1)
>>> d.number = 2
>>> print(c.number, d.number)
(2, 2)

为什么 cd 一样,不像 (a, b) 例子?如何在 (c, d) 类示例中的 (a, b) 中执行类似操作?即复制对象,然后更改其中的一部分(不会影响我借用属性的对象)?

最佳答案

这些行:

c = number("one", 1)
d = c

...有效:

  • 创建 number 的新实例并将其分配给 c
  • 分配名为 c 的现有引用到一个新变量 d

您没有更改或修改任何关于 c 的内容; d是指向同一个实例的另一个名称。

如果不克隆实例或创建新实例,您将无法执行与原始 int 行为类似的任何操作。


纠正一点信息,上面的解释是rather simplified有点不完整in its nature ,尽管它主要描述了 10,000 英尺处发生的情况。

为了仔细观察,我们必须了解 Python 的变量或“名称”,以及它们如何与该程序交互。

如上所述,you have the notion of "names" and "bindings" ,这很容易理解:

a = 3
b = a

在这种情况下,a是一个名字,b绑定(bind)到 a .我们没有修改或更改关于 a 的任何内容.

如前所述,Python 中有两种类型的数据:可变的和不可变的。指向不可变数据的名称(例如原语和元组)可以重新分配而不会对其上存在的任何其他绑定(bind)产生任何不良影响,因为相对于绑定(bind)没有状态发生变化。

这就是为什么这次重新分配符合我们的预期:

print(a, b)
b = 4
print(a, b)

b = 4 的结果是b现在指向一个整数的新副本,值 4。

回想一下,我确实提到元组是不可变数据。您不能更改元组中特定实体的绑定(bind)...

t = ('foo', 'bar')
t[0] = 'baz' # illegal

...但是您可以将可变数据结构作为这些绑定(bind)的一部分。

t = ([1, 2, 3], 'bar')
t[0].append([4, 5, 6]) # ([1, 2, 3, [4, 5, 6]], 'bar')

那么我们的例子在哪里呢?

c = number("one", 1)
d = c

number是一个 可变 类型,被命名为 c , 并且它的值可以在多个不同的绑定(bind)之间随意更改 c .

实际上,我们有一个名字和一个名字的绑定(bind):

  • 我们有一个 number 的新实例并通过名称 c 引用它.
  • 绑定(bind)引用 c换个名字d .

同样,c 没有任何变化, 但可以通过其他名称引用。

与不可变数据不同,当我们重新分配 d.number 的值时,我们正在重新分配与 c 相同的绑定(bind)意识到:

>>> id(d.number)
36696408
>>> id(c.number)
36696408

这就是您需要新实例或副本的原因。您必须引用 number 的另一个实例.使用这种简单的绑定(bind),您将无法做到这一点。

from copy import copy
c = number("one", 1)
d = copy(c)
id(c) # 140539175695784
id(d) # 140539175695856

关于python - 为什么变量 = 对象不像变量 = 数字那样工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29926485/

相关文章:

python - 函数 'hasattr()' 在 Python 中无法正常工作

python - Selenium 网络驱动程序 : form data not present after submit

javascript - ES6 block 范围变量定义作为条件

variables - DOS子字符串,其中Length为变量

python - 使用 Mechanize 处理非标准 401 header

Python:将值重新分配给变量(使用函数)

python - 两个列表的交集包括重复项?

Python-需要将控制台输出重定向到日志文件

python - 在 Spyder 中更改变量名称

python - 累计和与随机抽奖号码比较后返回列名