2016-05-10 21 views
0

说我的项目的结构是这样的:相对进口3

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得到这个工作..

+0

什么是你的问题? – zondo

+0

问题是,为什么我的本地日历模块正在加载? – Godsent

+0

因为这是模块正在搜索的第一个位置。 – DeepSpace

回答

2

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

如果您看到其他结果;这意味着要么你没有使用Python 3,要么尝试从一个包中运行一个Python模块作为脚本(myproject目录本身在sys.path中)。如果后者则您的calendar.py成为顶级模块,并且(由于当前目录在sys.path之前出现stdlib目录)from calendar import isleap从当前目录导入calendar.py"Never add a package directory, or any directory inside a package, directly to the Python path"

要避免它,不要直接在python包中运行模块,例如,不要这样做:cd myproject; python foo.py。做这个,而不是:python -mmyproject.foo(或者你可以define what scripts should be run in setup.pycreate a similar script manually: 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 
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 
-1

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