2017-04-19 83 views
1

這是一個簡單的問題,但我在SO中找不到類似的問題。 無論如何Python返回的引用是可用的嗎? (也許用簡單的黑客。)通過引用返回可能嗎?

返回引用的解釋:

def func(lst): 
    return reference of lst[2] somehow 

func([7, 8, 9, 10])  # returns 9 
func([7, 8, 9, 10]) = 11 # lst is changed to [7, 8, 11, 10] 

這種行爲是可以實現的?也許有一些運算符重載?

++這種用法在C的例子:Returning values by reference in C++

+0

@abccd那麼它有可能在C++,我想知道如果它可能在Python中。 – Rockybilly

+0

沒有「按參考回報」這樣的東西,也許你的意思是「通過參考來電」? – muratgu

+2

不完全。這將只適用於一個可變對象(列表,字典等)。 –

回答

0

在Python重新綁定=號,所以你不能返回一個C++ - 樣式的引用。和Python切片副本,所以試圖返回一個list切片並分配給不影響原始列表。

你可以得到不極端的措施最接近的將是迴歸的指數,並讓來電者用它來重新分配,例如:

def func(lst): 
    return ... some computed index, e.g. 2 ... 

mylist = [7, 8, 9, 10] 
mylist[func(mylist)]  # Gets 9 
mylist[func(mylist)] = 11 # mylist is changed to [7, 8, 11, 10] 

這是可怕的代碼雖然;通常情況下,您會編寫一個函數,以返回一個新的,突變的list(保留原始不變)或者將list變爲適當的位置(不返回任何內容,隱式地返回None)。

2

什麼你應該做的就是回到2,然後用其作爲索引到列表中,您傳遞:

lyst = [7, 8, 9, 10] 
def func(lst): 
    # ... 
    return 2 

lyst[func(lyst)] = 11 

可以創建封裝到容器加一個參考對象索引(或鍵,在字典中的情況下)的特定元素:

class ElementRef(object): 

    def __init__(self, obj, key): 
     self.obj = obj 
     self.key = key 

    @property 
    def value(self): return self.obj[self.key] 

    @value.setter 
    def value(self, value): self.obj[self.key] = value 

然後你的函數看起來是這樣的:

def func(lyst): 
    # ... 
    return ElementRef(lyst, 2) 

而且你可以通過設置其屬性value這樣修改的元素:

func(lyst).value = 11 

但我沒有看到很多的價值在此經過短短返回指數。特別是因爲如果在使用項目之前將項目添加到列表或從列表中刪除項目,則該對象可能變得毫無用處。顯式返回一個索引使得這是一個顯而易見的問題,但是如果你得到一個ElementRef,你可能會認爲它包含某種不具備的魔法。

+0

heh。即將編輯與我的答案類似的東西,但我認爲他們作爲單獨的答案更好地工作,所以我會避免重複。如果你想進一步,你可以使'ElementRef'成爲一個代理風格的類(通過'__getattr__'或類似的東西),所以除了改變被引用的值之外,你可以使用它作爲底層類型。沒什麼值得費心的,只是提到它是「如果你想編寫可怕的Python,因爲你是一個受虐狂」選項。 :-)不管。 – ShadowRanger

0
def func(lst): 
    return reference of lst[2] somehow 

如果你這樣做:

def func(lst): 
    return lst[2] 

a = [1, 2, [3]] 
b = func(a) 

然後ba[2]參考。更確切地說,ba[2]都是對同一個列表對象([3])的引用。

因此,

b.append(4) 
print(a) # --> [1, 2, [3, 4]] 

但是,你要明白,在Python中的賦值運算符=不發生變異的左手側,只分配一個新的名字到右側。

+0

你能提供文檔嗎? – Adrian

+0

@Adrian這個問題的答案和鏈接的外部資源非常全面:https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference – mkrieger1

0

你也可以做這樣的事情通過將任務作爲函數的參數,因爲Python不支持C++引用返回值:

def func(lst, change_val = None): 
    if change_val is not None: 
     lst[2] = change_val 
    return lst[2] 
lst = [7, 8, 9, 10] 
print(func(lst))  # prints 9 
print(func(lst, 11)) # prints 11; lst is changed to [7, 8, 11, 10] 
print(lst) # prints [7, 8, 11, 10] since it was changed before