[英]python: import numpy as np from outer code gets lost within my own user defined module
我正在為科學計算進行模擬,幾乎總是想成為交互式解釋器來模擬我的模擬輸出。 我正在嘗試編寫類來定義模擬對象(神經群體),並且我想通過在ipython中調用腳本%run test_class_WC.py
來正式化對這些類的測試。 由於包含類的模塊/文件在嘗試調試/添加功能時發生了變化,因此每次都會重新加載它。
./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
所以立即開始,我正在使用reload來確保已加載模塊的最新版本,從而獲得了最新的類定義-我確信這很笨拙(也許更險惡) ?),但這為%run WC_class.py
去了執行%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基本上定義了一堆默認參數,並定義了一個使用基本Euler集成進行更新的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模塊頂部來解決此問題,甚至可以通過from numpy import exp
test_class_WC中的from numpy import exp
進行操作,並將update()方法更改為包含exp()而不是np.exp()。 。,但我不打算這樣做,因為它很容易,我想學習所有這些名稱空間/模塊的工作原理,因此我不再是python的白痴。 為什么np在WC_unit名稱空間中迷路了? 是因為我要處理兩個不同的文件/模塊嗎? 函數內部對np.exp
的調用是否與此有關?
我也樂於接受有關改善我的工作流程和文件結構的建議,因為它似乎並不是特別的pythonic。 我的背景是MATLAB的,這可以幫助任何人理解。 我正在SublimeText2中編輯我的.py文件。 抱歉,代碼不是非常少,我一直很難重現該問題。
正確的方法是在子模塊頂部也import numpy as np
。 原因如下:
需要注意的關鍵是,在Python中, global
實際上意味着“在模塊級別共享”,並且每個模塊的命名空間彼此不同, 除非一個模塊從另一個模塊中顯式導入。 導入的模塊絕對無法到達其“父”模塊的名稱空間,這可能是一件好事,否則,您將擁有行為完全取決於導入該模塊的模塊中定義的變量的模塊。
因此,當堆棧跟蹤顯示global name 'np' is not defined
,它是在模塊級別討論它。 默認情況下,Python不允許WC_Class
模塊訪問其父模塊中的對象。
(順便說一句,effbot 簡要介紹了如何進行模塊間全局操作 )
另一個需要注意的關鍵是,即使在代碼的各個模塊中有多個import numpy as np
,該模塊實際上也只會被加載(即執行)一次。 加載后,可以在字典sys.modules
找到模塊(本身就是Python對象),並且如果該字典中已經存在模塊,則任何import module_to_import
語句import module_to_import
允許導入模塊訪問module_to_import
命名空間中的名稱。 因此, import numpy as np
分散在代碼庫中的多個模塊中並沒有浪費。
編輯:在更深入的研究中,effbot 對模塊導入中實際發生的事情進行了更深入(但仍然非常快速和簡單)的探索 。 為了更深入地探討該主題,您可能需要檢查Python 3文檔中新添加的導入系統討論 。
在Python中,導入每個模塊所需的每個模塊是正常的。 不要指望任何“全球”進口。 實際上沒有這樣的事情。 除了一個例外。 我發現
%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
,請使用最后一行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.