如何从上一级目录导入模块
对于我的Python应用程序,我有以下的目录结构:
\myapp
\myapp\utils\
\myapp\utils\GChartWrapper\
\myapp\model\
\myapp\view\
\myapp\controller\
我在\myapp\view\中的一个类需要导入一个叫做 GChartWrapper 的类。但是,我遇到了导入错误...
myview.py
from myapp.utils.GChartWrapper import *
这是错误信息:
<type 'exceptions.ImportError'>: No module named GChartWrapper.GChart
args = ('No module named GChartWrapper.GChart',)
message = 'No module named GChartWrapper.GChart'
我哪里做错了?我在Python中导入模块和类时真的很困难...
5 个回答
你可以改变Python查找文件的路径。
在你的源文件的顶部,添加:
import sys
sys.path.append("..")
或者你也可以改变环境变量:
export PYTHONPATH=..
在Python中,你不能随便从任意路径导入模块和包。相反,你应该使用包和绝对导入的方式,这样可以避免将来出现各种问题。
举个例子:
创建以下文件:
MyApp\myapp\__init__.py
MyApp\myapp\utils\__init__.py
MyApp\myapp\utils\charts.py
MyApp\myapp\model\__init__.py
MyApp\myapp\view\__init__.py
MyApp\myapp\controller\__init__.py
MyApp\run.py
MyApp\setup.py
MyApp\README
这些文件应该是空的,除了以下几个:
MyApp\myapp\utils\charts.py:
class GChartWrapper(object):
def __init__(self):
print "DEBUG: An instance of GChartWrapper is being created!"
MyApp\myapp\view\__init__.py:
from myapp.utils.charts import GChartWrapper
def start():
c = GChartWrapper() # creating instance of the class
MyApp\run.py:
from myapp.view import start
start()
就这样!当你运行入口文件(run.py
)时,它会调用视图中的一个函数,然后创建一个GChartWrapper类的实例。使用这种结构,你可以在任何地方导入任何东西并使用它。
另外,在MyApp\setup.py
中,你需要为MyApp\myapp包编写一个安装程序。可以使用distutils来编写:
from distutils.core import setup
setup(name='MyApp',
version='1.0',
description='My Beautiful Application',
author='Martin',
author_email='martin@xxxxxxx.com',
url='http://stackoverflow.com/questions/1003843/',
packages=['myapp'],
scripts=['run.py']
)
这就足够了。现在,当人们下载MyApp文件夹时,他们只需使用setup.py进行安装,然后通过run.py运行它。Distutils可以生成多种格式的包,包括可以在Windows上安装的.EXE文件。
这就是分发Python包和应用程序的标准方式。
GChartWrapper这个包的__init__.py
文件要求在PYTHONPATH中包含GChartWrapper包。你可以通过文件的第一行看到这一点:
from GChartWrapper.GChart import *
那么,GChartWrapper包是否必须放在你的包目录结构里呢?如果是这样,你可以在运行时把包所在的路径添加到sys.path中。假设myview.py
文件是在myapp\view
目录下,你可以在导入GChartWrapper
之前这样做:
import sys
import os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'utils')))
如果不需要把它放在你的目录结构里,安装在常规位置可能会更简单。你可以通过运行GChartWrapper源代码包中的setup.py脚本来做到这一点。