2014-10-01 86 views
0

如果我创建了一个名为“json.py”,其内容如下模块:为什么这个Python3模块似乎执行自己的相对导入?

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

..shouldn't“导入JSON作为_json”语句执行的绝对导入,因此提供了Python标准 - lib JSON模块?

..instead,如果我执行或导入这个模块,我得到:

 
$ 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),但是,我也启动了一个脚本,它位于同一个包文件夹中(暂时),但并不意味着最终成为同一模块的一部分。因此,出现以下情况:

  • 我跑我的脚本,软件包名/ foo.py
  • 蟒蛇增加了包名的文件夹的sys.path
  • foo.py进口packagename.json
  • packagename.json进口json(通常是系统json)
  • sys.path上的第一项是packagename文件夹,'json'从那里导入
  • 我的json.py在导入后继续加载,并且运行时出错(因为它正在处理本身,而不是系统的json模块)

解决方案:将脚本来我的包的'bin文件夹,或者,如果我希望它是包装适当的一部分,使用python -m packagename.foo

谢谢,@Martijn彼得斯。

回答

3

做绝对导入。

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

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

Interface options documentation

如果脚本名称直接指Python文件,包含该文件的目录被加到的sys.path开始,该文件被作为__main__模块执行。

+0

呵呵。我当时认为从当前包中获取模块的唯一方法是使用'from。导入y'或(如果该软件包全局可用)'from mymodule import y'。谢谢,这是我需要的缺失细节。 – 2014-10-01 14:07:33

+1

@BrianVisel:尽管你没有包装。顶层脚本是*从不*包。如果您想将包用作脚本,请使用'-m'开关。 – 2014-10-01 14:08:24

+0

是的。这里有一个有趣的想法 - 如果有人不从脚本中移除'.py'扩展名,并且他们的脚本进入了某处的'bin /'文件夹,那么它可以被其他脚本导入,从而导致它们执行他们不打算的代码。当然,如果你允许将它安装在你的系统上,那么安全性已经存在问题。 – 2014-10-01 14:18:42

相关问题