2016-09-02 45 views
1

我有一个属性是一个列表的对象。例如:python - 按值或按引用传递

obj.a = [3, 4, 5] 

我想获得以下行为(但我不能管理使用魔法的/ etc找到一个解决方案。):

l = obj.a 
obj.a[0] = 2 

print(l) --> [3, 4, 5] 
print(obj.a) ---> [2, 4, 5] 

当然,我可以简单地使用拷贝.deepcopy:

l = copy.deepcopy(obj.a) 

但出于几个原因,我想以某种方式使此步骤自动/隐藏它为我的用户。

[编辑] 使用的getAttribute并返回一个副本当然不是工作:

import copy 
class Test: 
    def __init__(self): 
     self.a = [] 

    def __getattribute__(self, attr): 
     if attr == 'a': 
      return copy.deepcopy(super(Test, self).__getattribute__(attr)) 

任何帮助表示赞赏!

Thnak你, 托马斯

+3

如果您不想在操作过程中使用副本并在操作过程中将其留在操作过程中而没有在操作过程中明确复制列表,则无法执行此操作。换句话说,从python的角度来看,从第一行到第二行的'obj.a'访问没有什么不同,所以没有魔法信号可以让你隐藏某些情况下的复制操作,而不是其他情况。 – mgilson

+0

[如何在Python中复制或复制列表?]可能重复(http://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list-in-python) – deceze

+1

你可能重写'obj.a'属性总是返回一个列表的副本...但是,这将是相当昂贵的,并打破了许多假设,你*期望*不*复制的正常行为。当你需要一份副本时,明确地说明它。 – deceze

回答

1

这是不可能使分配l = obj.a使obj.a副本。正如deceze在评论中所说的,你可以让a成为每次访问时都会返回一个值副本的属性,但是每次访问它时都会复制一份,而不仅仅是当您将其分配给l时。这将是低效的,并且可能不是你想要的行为无论如何

有没有办法为objobj.a告诉的东西之间的这样的差异:

x = obj.a 

这:

obj.a[:2] 

无论您在访问obj.a时发生什么,都会在两种情况下发生。你不能“向前看”,看看它是否将被分配给一个变量,只是为了在该特定情况下复制它。

+0

谢谢你的回答。我想我想要的行为接近于某些语言中所谓的Value Class! –

0

只需使用下面的代码...

l = list(obj.a) 

,这将让你列表复制到一个新的列表

0

这也不是没有可能实际上克隆列表到另一个列表中,你有根据您的要求使用copy()或deepcopy()。