如何从上一级目录导入模块

10 投票
5 回答
10465 浏览
提问于 2025-04-15 12:17

对于我的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 个回答

2

你可以改变Python查找文件的路径。

在你的源文件的顶部,添加:

import sys
sys.path.append("..") 

或者你也可以改变环境变量:

export PYTHONPATH=..
5

在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包和应用程序的标准方式。

7

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脚本来做到这一点。

撰写回答