2016-09-02 83 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()。