模块导入:NameError:名称未定义。

3
如何在导入器中定义函数,以便在导入的模块内可见?我尝试了以下代码: importer.py文件如下:
def build():
    print "building"

build()

import imported

因此,imported.py 简单地被导入。
build()

然而,这仍然失败了。
building
Traceback (most recent call last):
  File "C:\Users\valentin\Desktop\projects\maxim\miniGP\b01\evaluator\importer.py", line 6, in <module>
    import imported
  File "C:\Users\valentin\Desktop\projects\maxim\miniGP\b01\evaluator\imported.py", line 1, in <module>
    build()
NameError: name 'build' is not defined
更新:在我得到关于循环导入的响应之后,以便导入和被导入彼此依赖,我感到需要澄清这并不总是好的。我的目的是在被导入的模块中指定一些常见策略。它将使用一些用户定义的函数,例如build。用户定义所需的函数,并调用策略。关键是共享策略不能依赖于特定的用户定义。我认为,我需要像evaluate(imported.py)这样的东西来代替import,我相信这是任何脚本语言(包括Python)中的基本函数。irc://freenode/python 坚持要我使用import,但我不明白如何做到这一点。

我们有些困惑,因为这正是import的作用,它会导入模块本身,从而产生副作用。(因此,如果foo.py包含bar = 1 + 1,并且你import foo,那么你就可以访问foo.bar == 2,因为foo.py已经被执行了!) - Izkata
我不明白你在说哪个困惑。 - Val
3个回答

12

importer.py

def build():
   print("building")

build() #this extra call will print "building" once more.

imported.py

from importer import build
build()

请注意,importer.py和imported.py必须位于同一目录下。我希望这能解决您的问题。


这不会创建循环引用吗?print("building")会执行多少次? - Val
无论您调用多少次build()函数,它只会打印一次。对于我的情况,它只会打印一次。 - SujitS
4
你试过了吗!使用import的意思是引用你的模块,而不是执行它。在被导入的文件中调用build()函数实际上会调用importer.py中的函数,该函数最多只会执行一次。所以在提问之前先试试吧。 - SujitS
1
我已经尝试过了,在我的笔记本电脑上只有一次,而使用2个build()函数则是两次。请仔细检查您的问题,我相信这不是Python的方式。 - SujitS
1
我发现我需要execfile。不幸的是,对手不允许我将其作为答案。但是我们可以在这里保留正确的答案。 - Val
显示剩余8条评论

7

导入不是包含:它们是幂等的,应始终位于模块的顶部

不存在循环引用;一旦看到 import foo,进一步的 import foo 实例将不会再次加载该模块。

您正在获取 NameError,因为在 imported.py 的上下文中,没有名称为 build,它被称为 importer.build()

我不知道您尝试使用如此奇怪结构的代码做什么。


导入器定义了一些函数并调用了一些常见的代码。这样你就可以将你的常见代码参数化。在这种正常情况下没有什么奇怪的。 - Val

-14

我知道这是一种亵渎,但是在 Python 中作为脚本语言,允许导入模块而不将其与导入者绑定的功能很容易实现。您可以始终使用 execfile 来评估文件。


8
execfile()不是“亵渎”,而是一个明显的糟糕想法。同时,它与导入模块的方式不同。从你的问题中可以看出这是你想要的,但是不清楚为什么你要这么做。在Python中这不是正常的事情,因此应该根据Python的结构来组织你的项目。 - Thomas Wouters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接