簡體   English   中英

python:在我自己的用戶定義模塊中,將numpy作為外部代碼中的np丟失

[英]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中,導入每個模塊所需的每個模塊是正常的。 不要指望任何“全球”進口。 實際上沒有這樣的事情。 除了一個例外。 我發現

在Ipython中運行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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM