2014-01-16 42 views
1

這可能看起來像一個非常愚蠢的問題,但我對Python中的作用域規則感到困惑。在下面的例子中,我將兩個帶有值的變量(x,y)發送給一個應該改變其值的函數。當我打印結果時,變量沒有改變。如何更改函數中變量的範圍? Python

def func1(x,y): 
    x=200 
    y=300 

x=2 
y=3 

func1(x,y) 

print x,y #prints 2,3 

現在,如果這是C++我想先引用(&),以該功能給他們,因此能夠改變它們的值。那麼Python中的equivilant是什麼?更重要的是,當你發送對象到函數時實際發生了什麼? Python是否會對這些對象進行新的引用?

+0

此外,[Python:如何通過引用傳遞變量?](http://stackoverflow.com/q/986006/395760)。 – delnan

+0

**全部** Python名稱是對象的引用。函數參數僅與傳入的對象綁定。您沒有獲得內存位置,在表達式中使用它時總是取消引用名稱。作業正在重新綁定,而不是改變原始的存儲位置。因此,'x = 200'正在創建一個新對象('int(200)'),並將該對象的引用存儲在'x'中。 –

+0

內部作用域具有對來自外部作用域的*訪問*變量的隱式權限,但需要顯式權限才能修改來自外部作用域的變量。這簡直就像我可以說的那樣。 – roippi

回答

4

認爲它們是功能的一部分。當函數結束時,它的所有變量也會死掉。

x=2 
y=3 

def func(x,y): 
    x=200 
    y=300 

func(x,y) #inside this function, x=200 and y=300 
#but by this line the function is over and those new values are discarded 
print(x,y) #so this is looking at the outer scope again 

如果你想有一個功能恰好你寫的方式修改的值,你可以使用一個global但是這是非常不好的做法。

def func(x,y): 
    global x #these tell the function to look at the outer scope 
    global y #and use those references to x and y, not the inner scope 
    x=200 
    y=300 

func(x,y) 
print(x,y) #prints 200 300 

這裏的問題是,它使調試在最好的情況下的噩夢,並完全在最壞的情況下不可思議的是不可能的。像這些東西通常被稱爲函數中的「副作用」 - 設置一個你不需要設置的值,而不顯式地返回它是一件壞事。一般來說,你應該編寫修改項目的唯一函數是對象方法(像[].append()修改列表,因爲它很愚蠢,以返回一個新的列表!)

做這種事情的正確方法是使用一個返回值。嘗試類似

def func(x,y): 
    x = x+200 #this can be written x += 200 
    y = y+300 #as above: y += 300 
    return (x,y) #returns a tuple (x,y) 

x = 2 
y = 3 
func(x,y) # returns (202, 303) 
print(x,y) #prints 2 3 

爲什麼沒有工作?那麼因爲你從來沒有告訴程序去做任何事情,只需要計算它。現在我們來分配它

#func as defined above 

x=2 ; y=3 
x,y = func(x,y) #this unpacks the tuple (202,303) into two values and x and y 
print(x,y) #prints 202 303 
+0

如何使用函數更改x,y? –

+0

在函數末尾顯式返回x,y,然後調用'x,y = func(x,y)' – jonrsharpe

+0

@ Reboot_87:你不能;你傳入的對象是不可變的,因此不可能改變它們,並且你不能重新綁定外部作用域中的名稱*只是基於傳入的內容。(您可以使用'global'關鍵字在全局範圍內重新命名'x'和'y',但不管傳入什麼對象,都會發生這種情況;在這種情況下,func(a,b)只會修改x和y。 .. – geoffspear