导入我的 class 时,我无法访问其他模块的功能
When importing my class I lose access to functions from other modules
我正在尝试学习如何为科学计算进行面向对象的编码运行进行模拟;我正在使用 numpy 等。我创建了我的第一个 class、WC_unit
,它位于 ./classes/WC_class.py
(一个子目录)。我在 classes
目录中创建了一个 __init__.py
文件(它是空的)。
WC_unit
class 的方法需要一些 numpy 函数,比如 exp
当我 运行 来自终端的代码(在 ipython 中)时,使用
%run WC_class.py
我可以生成 class E1 = WC_unit()
的一个实例,我可以 运行 它上面的相关方法,即 E1.update()
我真的不知道它是否有效。我在位于的脚本 test.py
中编写了一些外部代码。 (在 ./classes
之上)测试我正在生成的对象,我正在尝试使用
导入 class
from classes.WC_class import WC_unit
现在,当我创建 class 和 运行 E1.update()
的实例 E1
时,我收到错误消息 global name 'exp' is not defined
.
我试过调用 from numpy import *
或 import numpy as np
并将函数调用更改为 np.exp()
,但我仍然遇到错误。考虑到我遇到了某种范围界定问题或命名空间问题,我将相同的导入函数放在不同的位置,包括 test.py
文件、class 文件的顶部 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))
我真的很想提高我的水平,弄清楚如何编写我自己的 classes 并将它们与很棒的计算工具一起使用。我想我想知道:
我做错了什么(我怀疑可能很多)。我认为这与我导入 class 的方式有关?但也许也在 class 本身范围内。
为什么我的 class 在我 import
时无法访问 numpy 函数,但在我 运行 它就像终端中的脚本一样?
我想我通常也不明白为什么人们如此保护他们的命名空间,即为什么这么多代码示例显示 import numpy as 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 会话中调用了 from numpy import *
,所以 exp
在当前 'module' 的全局变量集中被定义为 numpy.exp
(其中,在在这种情况下,只是 IPython 交互式命名空间),因此当您在 WC_unit.update()
中调用 exp()
(或 WC_class.py
中的任何其他地方)时,它将正常工作。
但是,你没有在test.py
的顶部做一个from numpy import *
,因此当你将WC_unit
导入你的脚本时,exp
还没有被定义在当前模块的范围(现在是 test
脚本)。
您已经在 WC_unit.update()
方法本身中尝试了 from numpy import *
,但这会失败,因为 import *
is only allowed at a module level(事实上,您应该已经看到 SyntaxWarning
你试图导入 WC_unit
!)。由于导入失败,exp
仍未定义,WC_unit.update()
方法将引发您看到的 NameError
。
您应该做的是在任何使用 numpy 函数的源文件的顶部有一个导入行:
import numpy as np
然后通过 np.
命名空间引用任何 numpy 函数。
关于你的第三点,这样做的主要原因
import numpy as np
x = np.exp(y) # etc.
而不是
from numpy import *
x = exp(y) # etc.
是后一种方法污染了你的全局命名空间。
假设您已经定义了自己的函数 exp
。当您执行 from numpy import *
时,您将用 numpy.exp
覆盖您自己的名为 exp
的函数,因此当您稍后调用 exp(y)
时,它可能不会执行您期望的操作。例如,这正是某些内置 Python 函数(例如 sum
和 all
:
所发生的情况
print(sum.__module__)
# __builtin__
from numpy import *
print(sum.__module__)
# numpy.core.fromnumeric
此外,这或多或少是不可逆的 - 一旦您完成了 from module import *
就没有简单的方法来摆脱您导入到命名空间的东西(或恢复任何旧的您通过在其顶部导入而破坏的模块或变量)。
只要您将每个模块的所有内容保存在其自己单独的命名空间中,就没有命名空间冲突的风险,并且每个函数或 class 的来源也不会含糊不清。按照惯例,我们使用 np
来引用 numpy 的命名空间,plt
用于 matplotlib.pyplot
等
我正在尝试学习如何为科学计算进行面向对象的编码运行进行模拟;我正在使用 numpy 等。我创建了我的第一个 class、WC_unit
,它位于 ./classes/WC_class.py
(一个子目录)。我在 classes
目录中创建了一个 __init__.py
文件(它是空的)。
WC_unit
class 的方法需要一些 numpy 函数,比如 exp
当我 运行 来自终端的代码(在 ipython 中)时,使用
%run WC_class.py
我可以生成 class E1 = WC_unit()
的一个实例,我可以 运行 它上面的相关方法,即 E1.update()
我真的不知道它是否有效。我在位于的脚本 test.py
中编写了一些外部代码。 (在 ./classes
之上)测试我正在生成的对象,我正在尝试使用
from classes.WC_class import WC_unit
现在,当我创建 class 和 运行 E1.update()
的实例 E1
时,我收到错误消息 global name 'exp' is not defined
.
我试过调用 from numpy import *
或 import numpy as np
并将函数调用更改为 np.exp()
,但我仍然遇到错误。考虑到我遇到了某种范围界定问题或命名空间问题,我将相同的导入函数放在不同的位置,包括 test.py
文件、class 文件的顶部 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))
我真的很想提高我的水平,弄清楚如何编写我自己的 classes 并将它们与很棒的计算工具一起使用。我想我想知道:
我做错了什么(我怀疑可能很多)。我认为这与我导入 class 的方式有关?但也许也在 class 本身范围内。
为什么我的 class 在我
import
时无法访问 numpy 函数,但在我 运行 它就像终端中的脚本一样?我想我通常也不明白为什么人们如此保护他们的命名空间,即为什么这么多代码示例显示
import numpy as 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 会话中调用了 from numpy import *
,所以 exp
在当前 'module' 的全局变量集中被定义为 numpy.exp
(其中,在在这种情况下,只是 IPython 交互式命名空间),因此当您在 WC_unit.update()
中调用 exp()
(或 WC_class.py
中的任何其他地方)时,它将正常工作。
但是,你没有在test.py
的顶部做一个from numpy import *
,因此当你将WC_unit
导入你的脚本时,exp
还没有被定义在当前模块的范围(现在是 test
脚本)。
您已经在 WC_unit.update()
方法本身中尝试了 from numpy import *
,但这会失败,因为 import *
is only allowed at a module level(事实上,您应该已经看到 SyntaxWarning
你试图导入 WC_unit
!)。由于导入失败,exp
仍未定义,WC_unit.update()
方法将引发您看到的 NameError
。
您应该做的是在任何使用 numpy 函数的源文件的顶部有一个导入行:
import numpy as np
然后通过 np.
命名空间引用任何 numpy 函数。
关于你的第三点,这样做的主要原因
import numpy as np
x = np.exp(y) # etc.
而不是
from numpy import *
x = exp(y) # etc.
是后一种方法污染了你的全局命名空间。
假设您已经定义了自己的函数 exp
。当您执行 from numpy import *
时,您将用 numpy.exp
覆盖您自己的名为 exp
的函数,因此当您稍后调用 exp(y)
时,它可能不会执行您期望的操作。例如,这正是某些内置 Python 函数(例如 sum
和 all
:
print(sum.__module__)
# __builtin__
from numpy import *
print(sum.__module__)
# numpy.core.fromnumeric
此外,这或多或少是不可逆的 - 一旦您完成了 from module import *
就没有简单的方法来摆脱您导入到命名空间的东西(或恢复任何旧的您通过在其顶部导入而破坏的模块或变量)。
只要您将每个模块的所有内容保存在其自己单独的命名空间中,就没有命名空间冲突的风险,并且每个函数或 class 的来源也不会含糊不清。按照惯例,我们使用 np
来引用 numpy 的命名空间,plt
用于 matplotlib.pyplot
等