如何在 python 中创建对变量的引用?
- 2025-01-22 08:46:00
- admin 原创
- 85
问题描述:
在代码中:
y = 7
x = y
x = 8
y
将是 7,而 x 将是 8。但我实际上想同时x
更改。我可以指定引用并执行此操作吗?y
`y`
例如,在 C++ 中可以通过以下方式实现相同的目的:
int y = 8;
int &x = y;
x = 9;
现在,y
和都x
将是 9。
解决方案 1:
不,你不能。正如其他答案指出的那样,你可以(滥用?)使用可变对象的别名来实现类似的效果。但是,这与 C++ 引用不同,我想解释一下实际发生了什么,以避免任何误解。
您会看到,在 C++(和其他语言)中,变量(以及对象字段、集合中的条目等)是一个存储位置,您将一个值(例如,一个整数、一个对象或一个指针)写入该位置。在此模型中,引用是存储位置(任何类型)的别名 - 当您分配给非引用变量时,您会将一个值(即使它只是一个指针,它仍然是一个值)复制到存储位置;当您分配给引用时,您会复制到其他存储位置。请注意,您无法更改引用本身 - 一旦绑定(并且必须在您创建引用后立即绑定),对它的所有赋值都不会改变引用,而是改变所引用的内容。
在 Python(和其他语言)中,变量(以及对象字段、集合中的条目等)只是一个名称。值位于其他地方(例如,散布在整个堆中),变量引用(不是 C++ 引用的意义,更像是指针减去指针算法)一个值。多个名称可以引用同一个值(这通常是一件好事)。Python(和其他语言)将引用值所需的任何内容称为引用,尽管与 C++ 引用和传递引用之类的东西毫无关系。分配给变量(或对象字段等)只会使其引用另一个值。整个存储位置模型不适用于 Python,程序员从不处理值的存储位置。他存储和移动的都是 Python 引用,而这些不是 Python 中的值,因此它们不能成为其他 Python 引用的目标。
所有这些都与值的可变性无关 - 例如,对于 int 和列表也是如此。您不能获取引用任一变量的变量并覆盖它指向的对象。您只能告诉对象修改其自身的部分内容 - 比如,更改它包含的某些引用。
这是一个更严格的模型吗?也许吧,但大多数情况下它已经足够强大了。当它不够强大时,你可以使用下面给出的自定义类或(等效但不太明显的)单元素集合来解决这个问题。
class Reference:
def __init__(self, val):
self._value = val # just refers to val, no copy
def get(self):
return self._value
def set(self, val):
self._value = val
这仍然不允许您为“常规”变量或对象字段设置别名,但您可以让多个变量引用同一个Reference
对象(可变单例集合替代方案也是如此)。您只需小心始终使用.get()
/ .set()
(或[0]
)。
解决方案 2:
不,Python 没有这个功能。
如果你有一个列表(或任何其他可变对象),你可以通过改变 x 和 y 绑定的对象来做你想做的事情:
>>> x = [7]
>>> y = x
>>> y[0] = 8
>>> print x
[8]
在线查看其工作原理:ideone
解决方案 3:
或者,您可以使用自制的容器。
class Value(object):
def __init__(self, value): self.value = value
y = Value(7)
x = y
x.value = 8
print y.value
艾迪酮
解决方案 4:
您应该为此使用可变对象。
在 python 中x
&y
只是对对象的引用,所以y = 7
意味着 y 指向对象7
。x=y
意味着x
也指向7
,但由于7
是不可变的,所以改变 x 的值只会改变对象7
并且y
仍然指向7
。
>>> y = [7]
>>> x = y
>>> x[0] = 8 # here you're changing [7] not x or y, x & y are just references to [7]
>>> y
[8]
解决方案 5:
虽然它与 C++ 中的引用不同,但根据使用情况,人们可能会在 Python 标准库中找到Weakref模块。
对对象的弱引用不足以使对象保持活动状态:当对引用对象的唯一剩余引用是弱引用时,垃圾回收可以自由地销毁引用对象并将其内存重新用于其他内容。但是,在对象真正被销毁之前,即使没有对它的强引用,弱引用也可能返回该对象。
弱引用的主要用途是实现保存大对象的缓存或映射,在这种情况下,希望大对象不要仅仅因为出现在缓存或映射中而保持活动状态。
解决方案 6:
我想知道函数 eval() 和 exec() 是否能满足您的需求。
y = 7
x = "y"
eval(x) # 7
y = 8
eval(x) # 8
exec(x+"=9")
y # 9
eval(x) # 9
但我同意,如果你习惯了 C 中的指针,那么没有它们生活会很困难。生活中的女人也一样。所以如果我们在生活中或 Python 中失去了她们,我们会尽最大努力把她们找回来…… :-)