2015-02-11 90 views
1

我正在做科學計算的模擬,而且我幾乎總是想要在交互式解釋器中查找輸出我的模擬。我試圖編寫類來定義模擬對象(神經人羣),我想通過在ipython中調用腳本%run test_class_WC.py來正式確定我對這些類的測試。由於包含該類的模塊/文件在我嘗試調試/添加功能時發生了變化,因此我每次都要重新加載它。python:import numpy as np from external code gets in my own user defined module

./test_class_WC.py:

import WC_class # make sure WC_class exists 
reload(WC_class) # make sure it's the most current version 
import numpy as np 

from WC_class import WC_unit # put the class into my global namespace? 

E1 = WC_unit(Iapp=100) 
E1.update() # see if it works 
print E1.r 

所以馬上我使用重載使蝙蝠肯定我明白了加載模塊的最新版本,所以我有最新鮮的類definition--我敢肯定,這是笨重赫克(也許更險惡?),但它節省了我做%run WC_class.py和不得不做一個單獨的呼叫%run test_WC.py

和./WC_class一些麻煩:

class WC_unit: 

    nUnits = 0 
    def __init__(self,**kwargs): 
     self.__dict__.update(dict(  # a bunch of params 
       gee = .6,    # i need to be able to change 
       ke=.1,the=.2,   # in test_class_WC.py 
       tau=100.,dt=.1,r=0.,Iapp=1.), **kwargs) 
     WC_unit.nUnits +=1 

    def update(self): 
     def f(x,k=self.ke,th=self.the): # a function i define inside a method 
      return 1/(1+np.exp(-(x-th)/k)) # using some of those params 
     x = self.Iapp + self.gee * self.r 
     self.r += self.dt/self.tau * (-self.r + f(x)) 

WC_unit基本上定義了一堆默認參數,並定義了使用基本歐拉積分進行更新的ODE。我希望test_class_WC建立含有NP一個全局命名空間(和WC_unit和WC_class)

當我運行它,我得到以下錯誤:

In [14]: %run test_class_WC.py 
--------------------------------------------------------------------------- 
NameError         Traceback (most recent call last) 
/Users/steeles/Desktop/science/WC_sequence/test_class_WC.py in <module>() 
     8 
     9 E1 = WC_unit(Iapp=100) 
---> 10 E1.update() 
    11 
    12 # if bPlot: 

/Users/steeles/Desktop/science/WC_sequence/WC_class.py in update(self) 
    19       return 1/(1+np.exp(-(x-th)/k)) 
    20     x = self.Iapp + self.gee * self.r 
---> 21     self.r += self.dt/self.tau * (-self.r + f(x)) 
    22 
    23   # @class_method 

/Users/steeles/Desktop/science/WC_sequence/WC_class.py in f(x, k, th) 
    17   def update(self): 
    18     def f(x,k=self.ke,th=self.the): 
---> 19       return 1/(1+np.exp(-(x-th)/k)) 
    20     x = self.Iapp + self.gee * self.r 
    21     self.r += self.dt/self.tau * (-self.r + f(x)) 

NameError: global name 'np' is not defined 

現在我可以只導入numpy的解決這個問題作爲np在WC_class模塊的頂部,或者甚至在test_class_WC中執行from numpy import exp,並將update()方法更改爲包含exp()而不是np.exp()...但我沒有試圖這樣做,因爲它很容易,我想了解所有這些命名空間/模塊的東西如何工作,所以我不再是一個蟒蛇白癡。爲什麼np在WC_unit命名空間中迷路了?是因爲我正在處理兩個不同的文件/模塊?在函數內調用np.exp是否與它有關?

對於改進我的工作流程和文件結構,我也很樂於提供建議,因爲它似乎不是特別pythonic。如果這有助於任何人理解,我的背景是在MATLAB中。我正在編輯SublimeText2中的.py文件。抱歉,代碼不是非常小,我一直在很難再現問題。

+0

您需要在'WC_class.py'的頂部將'numpy導入爲np' – 2015-02-11 02:15:52

回答

2

正確的方法是在子模塊的頂部也執行import numpy as np。這裏的原因:

要注意的關鍵問題是,在Python,global實際上是指「在模塊級共享」,並且每個模塊的命名空間存在明顯的相互除了當一個模塊明確地從另一個出口模塊。一個導入的模塊肯定無法接觸到它的'父'模塊的命名空間,這可能是所有事情都考慮過的一件好事,否則你將擁有模塊,它們的行爲完全取決於導入模塊的變量。

所以當堆棧跟蹤說global name 'np' is not defined,它是在模塊級別談論它。默認情況下,Python不允許WC_Class模塊在其父模塊中訪問對象。

(順便說一句,effbot有quick note on how to do inter-module globals

需要注意的是,即使你在你的代碼中各個模塊的多個import numpy as np,該模塊實際上只被載入另一個關鍵的事情(即執行)一次。加載後,模塊(本身就是Python對象)可以在字典sys.modules中找到,並且如果此字典中已存在模塊,則任何import module_to_import語句都只允許導入模塊訪問名稱空間module_to_import中的名稱。因此,將import numpy as np分散在代碼庫中的多個模塊中並不是浪費。

編輯:在更深的挖掘,effbot有even deeper (but still pretty quick and simple) exploration of what actually happens in module imports。要深入探討該主題,您可能需要檢查在Python 3文檔中新添加的import system discussion

0

在Python中導入每個模塊所需的每個模塊是正常的。不要指望任何'全球'進口。事實上並沒有這樣的事情。有一個例外。我在

Do I have to specify import when Python script is being run in Ipython?

%run -i myscript運行在IPython中的互動命名空間腳本

發現。因此,對於快速測試腳本,這可以節省一大堆導入。

我沒有看到這三重進口

import WC_class # make sure WC_class exists 
reload(WC_class) # make sure it's the most current version 
... 
from WC_class import WC_unit 

的需求。如果你是從WC_class使用只需使用的最後一行。

相關問題