模块导入两次。 Python解释器中可能存在的错误

时间:2011-12-27 12:25:49

标签: python interpreter

我在我的一个项目中做了一个相当人为的导入方案,我想我可能在Python解释器中发现了导致模块导入两次的错误。

以下是我的测试项目的设置方式:

  • /

    • Launcher.bat - 项目从此处开始运行。它使用Python 3.2可执行文件

    • 启动'main / __ init __。py`
    • main / __ init __。py - __main__脚本,由'Launcher.bat'启动的脚本

    • main / foo.py - 包含空类

    • external / __ init __。py - “主”项目脚本外部的脚本,用于演示问题

./ Launcher.bat

@echo off
C:\Python32\python.exe main\__init__.py
pause

./主/ __初始化__。PY

from foo import Foo
print("In 'main', Foo has id:", id(Foo))

# Add the directory from which 'Launcher.bat' was run,
# which is not the same as the './main' directory
# in which this script is located
import sys
sys.path.insert(1, '.')


# This script will try to import class Foo, but in doing so
# will casue the interpreter to import this './main/__init__.py'
# script a second time.
__import__('external')

./主/ foo.py

class Foo:
    pass

./外部/ __初始化__。PY

from main.foo import Foo
print("In 'external', Foo has id:", id(Foo))

所有这些都将打印'Main script was imported'消息两次。如果外部脚本导入任何其他脚本,那么这些脚本也将导入两次。我只在Python 3.2上测试过这个。这是一个错误,还是我犯了错误?

该计划的输出是:

  

在'main'中,Foo有id:12955136
  在'main'中,Foo有id:12955136
  在'外部',Foo有id:12957456
  按任意键继续 。 。 。

2 个答案:

答案 0 :(得分:2)

我不认为这是一个错误。您应该在python-dev列表中询问更权威的答案。您正在执行一次(当您运行脚本时)并导入一次(从外部),因此该行被打印两次。它不会导入两次。

然而,这是一个可怕的设置。这里有很多违规风格。虽然有些仅用于演示目的,但它仍然非常混乱。

  1. 您不应将包__init__.py文件用作应运行的文件。主入口点应该是导入包的脚本。
  2. 您不应该导入导入模块的导入模块。就像你外在的主要做法。

答案 1 :(得分:1)

第一个print具有误导性:由于您没有导入,但是第一次执行该文件(__name__ == '__main__'成立),主模块只导入一次。将起点移动到辅助文件中,或检查__name__ == '__main__'

顺便说一下,circular import是一个坏主意。您应该解决循环导入(通过将foo移动到专用库)。或者,您可以使模块可重入(即在添加之前检查当前目录是否在sys.path中)。