【问题标题】:How to import a module from a directory on level above the current script如何从当前脚本上方的目录中导入模块
【发布时间】:2009-06-16 20:42:51
【问题描述】:

对于我的 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 中导入模块/类...

【问题讨论】:

    标签: python import gchart


    【解决方案1】:

    GChartWrapper 包的__init__.py file 需要 PYTHONPATH 上的 GChartWrapper 包。你可以从第一行看出:

    from GChartWrapper.GChart import *
    

    是否有必要在你的包目录结构中包含 GChartWrapper 包? 如果是这样,那么您可以做的一件事是在运行时将包所在的路径添加到 sys.path。我认为myview.pymyapp\view 目录中?然后你可以在导入GChartWrapper之前这样做:

    import sys
    import os
    sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'utils')))
    

    如果不需要将它放在您的目录结构中,则将其安装在常规位置可能会更容易。您可以通过运行 GChartWrapper 源代码分发中包含的 setup.py 脚本来实现。

    【讨论】:

    • 我正在尝试在 App Engine 上使用 GChartWrapper,因此我无法真正运行设置。谢谢! :)
    【解决方案2】:

    您不会从任意路径导入模块和包。相反,在 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 包/应用程序的标准方式。

    【讨论】:

      【解决方案3】:

      您可以更改python查找文件的路径。

      在源文件的顶部,添加:

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

      或者改变环境变量:

      export PYTHONPATH=..
      

      【讨论】:

        【解决方案4】:

        或从 python 2.5 开始(再次假设 myview 在 myapp\view 中:

        from __future__ import absolute_import
        from ..utils.GChartWrapper import *
        

        见:http://docs.python.org/whatsnew/2.5.html#pep-328-absolute-and-relative-imports

        【讨论】:

          【解决方案5】:

          GChartWrapper 也可从 PyPI 获得,因此您可以使用 easy_install 或 pip 安装模块:

          sudo pip install GChartWrapper==0.9
          

          它会自动添加到您的 PYTHONPATH 中,然后您可以将其从 /myapp/utils 目录中删除。如果您不能使用 sudo,请查看使用 virtualenv(和 virtualenvwrapper)。

          【讨论】:

            猜你喜欢
            • 2021-01-14
            • 2012-12-22
            • 1970-01-01
            • 1970-01-01
            • 2021-03-15
            • 1970-01-01
            • 2020-11-03
            • 1970-01-01
            • 2022-01-09
            相关资源
            最近更新 更多