无论是int还是类实例,都有可能通过引用复制变量吗?
我的目标是拥有两个相同对象的列表,当一个更改时,更改在第二个中可见.
换句话说,我需要指针:/
我只想要int,float和其他通常由value复制的标准类型,强制通过引用复制.这将使我的代码更加一致.
如果没有这种可能性,类包装器是最好的解决方案.
您可以在类中包装不可变对象:
class MutableWrapper(object):
def __init__(self, value):
self.value = value
a = MutableWrapper(10)
b = a
a.value = 20
assert b.value == 20
Run Code Online (Sandbox Code Playgroud)
Python总是通过引用工作,除非你明确要求一个副本(一个内置列表的片段被认为是"要求复制" - 但是一块numpy数组也可以通过引用工作).但是,正因为如此,alist=anotherlist; alist.sort()意味着单个列表对象(具有两个等效名称alist和anotherlist)被排序 - 您不能在同一列表对象上同时维护两个不同的排序.
因此,在这种情况下,您必须明确要求一个副本(例如alist=list(anotherlist)) - 并且一旦完成,两个不同的列表对象之间就不再有连接.你不可能两种方式:要么你通过引用工作(并且有一个列表对象,因此只有一个排序!),或者你做了一个副本(在这种情况下你最终得到两个单独的列表对象).
您可以利用到目前为止讨论的副本很浅的事实- 两个列表所引用的对象(项目)是相同的...除非您对任一列表中的项目执行删除,添加或重新分配(另一方面,可变项目的变异不会改变这种联系:它与上述任何一种情况完全独立且完全不同,因为删除,添加和重新分配是在列表上的操作,同时在项目上调用变异方法是对项目的操作- 项目对于引用它们的一个或多个列表上的任何操作都是无关紧要的,列表对于它们所引用的一个或多个项目的任何操作都是无视的.
除了保留两个列表并在一个对象中同步,如其他答案中所建议的那样,删除和添加的功能并不多; 但是对于项目的重新分配,如果这就是你所需要的,你可以通过添加一个间接层来将它们变成项目的变异 - 而不是直接引用项目的列表,让它引用例如单项子列表.例如:
>>> alist = list([x] for x in 'ciao')
>>> blist = list(alist)
>>> blist.sort()
>>> alist
[['c'], ['i'], ['a'], ['o']]
>>> blist
[['a'], ['c'], ['i'], ['o']]
>>> blist[-1][0] = 'z'
>>> blist
[['a'], ['c'], ['i'], ['z']]
>>> alist
[['c'], ['i'], ['a'], ['z']]
Run Code Online (Sandbox Code Playgroud)
无论是一个额外的间接级别的概念可以帮助你究竟正在试图做可言,只有你可以告诉,因为我们真的不知道它是什么,你正在尝试做的;-).
(编辑以显示取消引用同一内存位置的示例)
Luper Rouch 的方法在处理混合类型列表时非常准确。只需用容器包装不可变类型即可。
如果您确实坚持使用 C 样式数组,其中元素被限制为单一类型(整数数组、字符数组等),则可以使用该ctypes模块。除了使用 DLL 的 FFI 之外,它还允许您访问 C 数据类型和指针。
from ctypes import *
containerTYPE = POINTER( c_uint ) * 10 #Array of pointers to UINTs of size 10
containerA = containerTYPE()
containerB = containerTYPE()
for i in range( 10 ):
val = c_uint( i )
containerA[ i ] = pointer( val )
containerB[ -1 - i ] = pointer( val )
print "A\tB"
for i in range( 10 ):
print containerA[ i ].contents.value, "\t", containerB[ i ].contents.value
for i in range( 10 ): #affects both arrays
derefed = containerA[ i ].contents
derefed.value = i * 2
print
print "A\tB"
for i in range( 10 ):
print containerA[ i ].contents.value, "\t", containerB[ i ].contents.value
Run Code Online (Sandbox Code Playgroud)
结果:
A B
0 9
1 8
2 7
3 6
4 5
5 4
6 3
7 2
8 1
9 0
A B
0 18
2 16
4 14
6 12
8 10
10 8
12 6
14 4
16 2
18 0
Run Code Online (Sandbox Code Playgroud)