为什么这个Python3模块似乎执行自身的相对导入?

时间:2014-10-01 13:48:17

标签: python python-3.x python-import

如果我创建一个名为'json.py'的模块,其中包含以下内容:

#! python
import json as _json
JSONDecoder = _json.JSONDecoder

..不应该'import json as _json'语句执行绝对导入,因此提供python standard-lib JSON模块?

..相反,如果我执行或导入此模块,我得到:

$ python --version
Python 3.4.0
$ python relative_import/json.py 
Traceback (most recent call last):
  File "relative_import/json.py", line 3, in 
    import json as _json
  File "/home/silver/Projects/relative_import/json.py", line 6, in 
    JSONDecoder = _json.JSONDecoder
AttributeError: 'module' object has no attribute 'JSONDecoder'
$

..表明'json'正在导入自己(相对导入)。 ..我想我错过了一些东西 - python的导入系统一直让我感觉自然而直观,但在这种情况下,我迷失了。

编辑:我正在使用python 3.4

编辑:对于任何感兴趣的人,这是发生的事情: 我有一个包含一个名为'json'的模块,它取代了系统'json'。这很好(IMO),但是,我也开始了一个脚本,它位于同一个包文件夹中(暂时)但并不意味着最终成为同一模块的一部分。因此,发生了以下情况:

  • 我运行我的脚本packagename / foo.py
  • python将packagename文件夹添加到sys.path
  • foo.py导入packagename.json
  • packagename.json导入json(通常是系统json)
  • sys.path上的第一个条目是packagename文件夹,从那里导入'json'
  • 我的json.py在导入后继续加载,并遇到错误(因为它处理自身,而不是系统json模块)

解决方案:将脚本移动到我们包的'bin'文件夹中,或者,如果我希望它成为包正确的一部分,请使用python -m packagename.foo

谢谢你,@ Martijn Pieters。

1 个答案:

答案 0 :(得分:3)

进行绝对导入。

主脚本所在的目录已添加到sys.path,因此找到的第一个json是您的脚本。您正在运行python relative_import/json.py,因此Python将relative_import/添加到sys.path

请注意,主脚本名为__main__,因此import json会将脚本文件作为单独的新模块对象导入。您的代码有效加载了两次。

请参阅Interface options documentation

  

如果脚本名称直接引用Python文件,则包含该文件的目录将添加到sys.path的开头,并且该文件将作为__main__模块执行。