Python 导入类时,我无法从其他模块访问函数
我试图学习如何为运行模拟的科学计算进行面向对象的编码;我正在使用numpy等。我已经创建了我的第一个类,Python 导入类时,我无法从其他模块访问函数,python,numpy,import,scope,Python,Numpy,Import,Scope,我试图学习如何为运行模拟的科学计算进行面向对象的编码;我正在使用numpy等。我已经创建了我的第一个类,WC\u unit,它位于/classes/WC\u class.py(一个子目录)。我已经在类目录中创建了一个\uuuu init\uuuuuuuuuupy文件(该文件为空) WC\u单元类的方法需要一些numpy函数,如exp 当我从终端运行代码(在ipython中)时,使用 %run WC_class.py 我可以生成类E1=WC\u unit()的实例,并可以在其上运行相关的方法,即
WC\u unit
,它位于/classes/WC\u class.py
(一个子目录)。我已经在类
目录中创建了一个\uuuu init\uuuuuuuuuupy
文件(该文件为空)
WC\u单元
类的方法需要一些numpy函数,如exp
当我从终端运行代码(在ipython中)时,使用
%run WC_class.py
我可以生成类E1=WC\u unit()
的实例,并可以在其上运行相关的方法,即E1.update()
我真的不知道它是否有效。我在位于的脚本test.py
中编写了一些外部代码。(上图/classes
)来测试我正在生成的对象,并尝试使用
from classes.WC_class import WC_unit
现在,当我创建类的实例E1
并运行E1.update()
时,我得到错误消息全局名称“exp”未定义
我尝试从numpy import*调用,或者也尝试将import numpy as np
并将函数调用更改为np.exp()
,然后我继续得到错误。考虑到我在命名空间中遇到了某种范围问题,我将相同的导入函数放在了不同的位置,包括test.py
文件、类文件顶部的WC_class.py
,甚至在方法中:
class WC_unit:
def __init__(self): [assign default pars from a dict including r, dt, tau, and Iapp]...
def update(self):
from numpy import *
self.r += self.dt/self.tau * (-self.r + exp(self.Iapp))
我真的很想改进我的游戏,弄清楚如何编写自己的类,并将它们与很棒的计算工具一起使用。我想我想知道:
我做错了什么(我怀疑可能很多)。我想这和我如何导入我的课程有关?但也许也包括课堂本身的范围界定
为什么我的类在导入numpy函数时失去了对它的访问权,而在我像在终端中运行脚本一样运行它时却没有
我想我也不明白为什么人们对自己的名称空间如此保护,也就是说,为什么这么多代码示例显示将numpy导入为np
,并使用所有函数作为np.exp(x)
,等等,我没有太多的计算机科学背景,所以我可以从你提供的任何解释中受益匪浅-文档对我来说有点神秘
Python版本:2.7.8 | Anaconda 2.1.0(x86_64)|(默认,2014年8月21日,15:21:46)
[GCC 4.2.1(Apple Inc.build 5577)]
在Mac OSX 10.6.8上,当您在IPython中调用%run WC_class.py
时,您所做的是将源文件的内容直接加载到交互式命名空间中。因为您已经在IPython会话中从numpy import*
调用了,exp
在当前“模块”(在本例中,它只是IPython交互名称空间)的全局变量集中被定义为numpy.exp
,所以当您在WC\U unit.update()中调用(或WC_class.py
中的任何其他地方)它都可以正常工作
但是,您没有在test.py
的顶部执行from numpy import*
,因此当您将WC\u单元
导入脚本时,当前模块(现在是test
脚本)的范围内没有定义exp
您已经在WC\u unit.update()
方法本身中尝试了从numpy import*
导入,但这将失败,因为(事实上,您在尝试导入WC\u unit
!)时应该看到一个SyntaxWarning
),因为导入失败,exp
仍然未定义,并且WC\u unit.update()
方法将引发您看到的名称错误
您应该做的是在使用numpy函数的任何源文件的顶部有一个导入行:
import numpy as np
然后通过np.
名称空间引用任何numpy函数
关于你的第三点,主要原因是
import numpy as np
x = np.exp(y) # etc.
而不是
from numpy import *
x = exp(y) # etc.
后一种方法污染了全局名称空间
假设您已经定义了自己的函数exp
。当您从numpy import*
执行操作时,您将使用numpy.exp
覆盖自己的函数exp
,因此当您以后调用exp(y)时
它可能不会达到您期望的效果。例如,这正是某些内置Python函数(如sum
和all
)所发生的情况:
print(sum.__module__)
# __builtin__
from numpy import *
print(sum.__module__)
# numpy.core.fromnumeric
更重要的是,这或多或少是不可逆的-一旦您从模块导入中执行了*
,就没有简单的方法可以去除您导入到命名空间中的内容(或者通过导入它们上面的内容来恢复任何旧模块或变量)
只要您将每个模块的所有内容保留在自己单独的名称空间中,就不会有名称空间冲突的风险,也不会对每个函数或类的来源产生歧义。按照惯例,我们使用np
来引用numpy的名称空间,plt
来引用matplotlib.pyplot
等的名称空间。停止使用fromnumpy import*
和preferenceimport numpy
并使用numpy.array
、numpy.mean
等。这可以防止名称空间污染,这会造成您所看到的问题。请始终显示问题中任何错误消息的完整回溯谢谢!我不确定这是否确实发生了,但我已经知道了我确实能够更多地了解类和对象的工作方式,并将其分解为更小的部分。在我学习如何写作的过程中,我可能会问一些更具哲学意义的问题,我感谢你的透彻而直截了当的回答。如果有人能将我链接到任何关于如何使用类开发模拟的教程我很想读这些书