在Python 3相对于进口(relative import in Python 3)

2019-09-30 09:39发布

说我的项目的结构是这样的:

myproject
├── calendar.py
├── foo.py
└── __init__.py

在foo.py,我有

from calendar import isleap

我想在Python 3.x中,不使用明确的.calendar上面的代码应该加载内置的日历模块,而不是我自己的日历模块,但显然我的本地calendar.py仍在进口,因为没有它抛出一个错误在MYPKG / calendar.py 'isleap'。 为什么我的本地日历模块这里进口的?

我不得不重新命名calendar.py到cal.py得到这个工作..

Answer 1:

from __future__ import absolute_import是Python 3的默认因此from calendar import isleap语句导入顶层模块calendar

如果你看到其他的结果; 它要么你不使用Python 3,或者你正试图从一个包内的脚本(运行Python模块指myproject目录本身是sys.path )。 如果是后者那么你calendar.py成为顶层模块和(由于当前目录前STDLIB目录自带sys.pathfrom calendar import isleap进口calendar.py从当前目录。 “不要添加软件包的目录,或者任何一个目录包内,直接将Python路径”

为了避免它,不要直接例如Python包内运行的模块,不这样做: cd myproject; python foo.py cd myproject; python foo.py 。 做到这一点,而不是: python -mmyproject.foo (或者你可以定义哪些脚本应当运行setup.py或手动创建一个类似的脚本: from myproject import foo; foo.main()

如果你想运行一个Python包作为脚本然后创建myproject/__main__.py然后运行python -mmyproject


如果你想要做一个相对进口在Python 3; 做到这一点明确例如,在myproject/foo.py

from .calendar import something

或者做一个绝对的导入:

from myproject.calendar import something


Answer 2:

它看起来像你的路径或目录结构设置错了。

鉴于以下结构日历模块的全名应该是myproject.calendar 。 您可以通过打印出检查这个__name__您模块的属性。 对于这是事实,你的程序用来导入本地模块必须包含文件夹的路径myproject

myproject
├── calendar.py
├── foo.py
└── __init__.py

好像你正在使用的路径实际上是myproject 。 含义calendar.py变成根级别模块calendar ,而不是myproject.calendar 。 Python的喜欢本地模块内置的,所以导入您calendar模块。

更典型的,你可能会做这样的事情。

MyProjectFolder
├── main.py
└── myproject
    ├── calendar.py
    ├── foo.py
    └── __init__.py

然后运行你的程序是这样的:

#! /bin/bash
cd /path/to/MyProjectFolder
python main.py


Answer 3:

Python会检查你的本地模块,并通过首先加载它们import

from calendar import isleap将搜索模块calendar您所在区域包先。 如果没有找到,它会导入从内建库calendar

from .calendar import isleap只会从你的本地化模块导入calendar 。 如果没有找到,提出了一个例外ImportError

这就是为什么你应该在一个包中使用相对导入。

你可以做一个把戏一样,导入内建库没有本地模块的检查。 但是,这只是一个把戏。 我永远不会在生产中使用它。 你应该更好的重命名模块calendar

import imp, sys
f, pathname, desc = imp.find_module("calendar", sys.path[1:])
calendar = imp.load_module("calendar", f, pathname, desc)
f.close()

from calendar import isleap


文章来源: relative import in Python 3