说我的项目的结构是这样的:
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得到这个工作..
from __future__ import absolute_import
是Python 3的默认因此from calendar import isleap
语句导入顶层模块calendar
。
如果你看到其他的结果; 它要么你不使用Python 3,或者你正试图从一个包内的脚本(运行Python模块指myproject
目录本身是sys.path
)。 如果是后者那么你calendar.py
成为顶层模块和(由于当前目录前STDLIB目录自带sys.path
) from 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
它看起来像你的路径或目录结构设置错了。
鉴于以下结构日历模块的全名应该是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
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