2013-10-10 46 views
1

我寫了這個代碼:全球陣列 - 無需「全球」的聲明

sample_array = ones ([N, 3], dtype = float) 
def get_training_set(): 
    r = rand (N, 2) * 2 - 1 
    sample_array[:,[0,1]] = r 
    return sample_array 

我外面聲明的採樣陣列,爲了不分配這一切的時候,只是修改它 - 最後的座標總是1.

最初我期望我必須在函數中插入一個語句「global sample_array」,因爲我修改了它,因此評估者應該知道它是一個全局變量。

但是,令我驚訝的是,沒有「全球」,它運行良好。 它爲什麼有效?在這種情況下評估的定義在哪裏/什麼?

回答

1

global是必要的,如果您要更改對象的引用(例如與賦值)。如果你只是對對象進行變異(例如像上面所做的切片分配),則需要而不是

準確的文檔是here

全局聲明是一個適用於整個當前代碼塊的聲明。這意味着列出的標識符將被解釋爲全局變量。

因此,通過全局聲明,您告訴python變量存在於全局上下文中。如果分配給它,則在全局上下文中更改該值。

如果不使用全局語句,python會決定變量是本地還是非本地。 (其實python3.x增加了一個關鍵字nonlocal)。如果變量首先出現在作業的右側,或者如果您執行項目分配(x[...] = ...)或屬性分配(x.whatever = ...),則該變量爲非局部變量。如果變量是本地的,那意味着它是在函數中創建的(或者是一個輸入參數)。您可以直接重新分配到本地標識符,這沒有問題。如果變量是非本地變量,那麼可以對它進行變異,但不能重新賦值,因爲python無法確定變量是本地變量還是非本地變量。

+0

好。你能向我展示解釋這個的官方手冊/定義嗎? – alinsoar

+0

@alinsoar突變是當你改變'in place'時,這正是你在做的事情。如果你在**函數中定義了**,沒有返回它,然後在該函數外引用它**,那麼你需要一個'global'語句。 –

+0

@mgilson。我知道什麼是全球性的。但是,我看不出有關可變變量會發生什麼的直接定義。 – alinsoar

0

我認爲這是因爲sample_array沒有在函數內部聲明,而只是寫入。 Python無法在副函數名稱空間中找到sample_array,它會查找外部名稱空間。 例如

a = [] 

def test1(): 
    a.append(1) # will use the outer one 

def test2(): 
    a = [] 
    a.append(1) # will use the inner one 

全球,有時,對於聲明一個全局變量:

def declare_global(): 
    global b # this should be global after 'declare_global()' is called 
    b = 1 

print b # raise NameError: name 'b' is not defined 
declare_global() 
print b # will output '1' 
+0

我認爲我的問題有點不同;)它是關於可變變量,它們被視爲與正常變量不同。 – alinsoar

+0

對不起,我沒有得到poing> _ < – MorningBAI

+0

應該是'a.append(1)' - 括號,而不是'[]' – mgilson