2014-06-08 28 views
0

考慮下面的代碼片段:Canopy的IPython中`global`關鍵字如何工作?

a = '' 
def assign(letter): 
    global a 
    a = letter 

如果我加載這個處於空閒並運行它(的Python 2.7.6),它表現爲預期:

>>> a 
'' 
>>> assign('b') 
>>> a 
'b' 

但在IPython中內置的雨棚編輯器(1.3.1)全局變量沒有被函數改變:

In [2]: a 

Out[2]: '' 

In[3]: assign('b') 

In[4]: a 

Out[4]: '' 

這是預期的行爲嗎?如何在IPython中操作全局變量?

爲了記錄,我意識到全局變量的危險。我在嘗試重現類中討論的緩存例程時碰到了這個問題:https://www.youtube.com/watch?v=OgPS2ziCEaw

+2

這是一個Canopy特定的問題,我無法在Ipython中複製它。 –

+0

您是否可能從模塊中導入*代碼? – user2357112

+0

不,我只是運行它。 (坦率地說,我不太確定當IDLE或Canopy要求他們在解釋器中運行一個模塊時會做什麼,但我很驚訝他們做了不同的事情!) –

回答

1

1)IDLE沒有使用IPython,所以比較沒有那麼重要。

2)Canopy中的run命令提供了一個標準ipython %run魔術命令,您可以在Canopy的ipython命令行上看到它並執行它。

3)你所報告的是ipython run magic命令的正常行爲。第一次遇到時有點反直覺;簡單的解釋是,所運行的模塊的全局名稱空間不同於ipython解釋器的全局名稱空間。在你運行一個模塊後,它的名字空間被複制到解釋器的名字空間中(這就是爲什麼a在解釋器中被定義的原因),但是執行函數assign(它在模塊中定義並且其全局命令因此引用模塊全局名字空間) ,在模塊的命名空間中改變a,而不是在解釋器命名空間中的副本。

4)這可能看起來像是不必要的混淆行爲,但目的是確保從ipython提示符運行的模塊對解釋器名稱空間中可能存在的任何flotsam運行「乾淨」。 5)如果你不想要這種行爲,請使用%run -i mymodule.py,這會導致模塊直接在解釋器的全局命名空間中運行。如果你這樣做,你的例子和Idle一樣。在Canopy中,最簡單的方法是在python shell中按下箭頭以調用%run命令,然後編輯它以插入-i

6)上面的評論者Padraic說他不能在ipython中複製它。我可以看到的唯一解釋是他將IPython配置爲默認運行在-i模式下,或者他並未實際運行OP的代碼片段,而是直接在解釋器中執行這些命令,因此僅使用解釋器名稱空間。