简体   繁体   English

python中导入模块的歧义

[英]Ambiguity of import modules in python

I have a Python library that looks like this (contains packages): 我有一个看起来像这样的Python库(包含软件包):

|-- python_lib/
    |-- plotting.py
    |-- verification.py
    |-- io.py
    |
    |-- ensemble/
        | -- plotting.py
        | -- verification.py

However, I am having problems with ambiguous module imports. 但是,模棱两可的模块导入存在问题。 In ensemble.plotting.py I want to import the verification.py module from the top level ( python_lib ): ensemble.plotting.py我想导入verification.py从顶层(模块python_lib ):

# ensemble/plotting.py
import verification.obs as verobs

However, I get an import error as this tries to import the verification.py module from the ensemble directory, rather than the top level of the library. 但是,我收到一个导入错误,因为它试图从ensemble目录(而不是库的顶层)中导入verification.py模块。

I thought that the "abslute imports" feature would solve this: 我认为“绝对进口”功能可以解决此问题:

from ..verification import obs

but I get this error: 但是我得到这个错误:

ValueError: Attempted relative import beyond toplevel package

How do I target python_lib/verification.py as an import from python_lib/ensemble/*.py without trying to import the local package version? 如何在不尝试导入本地软件包版本的情况下,将python_lib/verification.py为从python_lib/ensemble/*.py导入?

I am using Python version 2.7. 我正在使用Python版本2.7。

  1. All your directories should contain files __init__.py , or they won't be recognized as packages. 您所有的目录都应包含__init__.py文件,否则它们将不会被识别为软件包。

  2. Your directory python_lib must be a known path. 您的目录python_lib必须是已知路径。 You said in a comment that your PYTHONPATH contains a path to python_lib , so that seems good. 您在评论中说,您的PYTHONPATH包含python_lib的路径,因此似乎不错。

  3. If you start with eg python_lib/ensemble/verification.py as your main entry point, then the directory python_lib/ensemble shadows your directory python_lib , and you have to manually tell Python that your script belongs to that package. 如果以python_lib/ensemble/verification.py作为主要入口,那么目录python_lib/ensemble目录python_lib ,并且您必须手动告诉Python您的脚本属于该软件包。

Like this: 像这样:

 if __name__ == "__main__" and __package__ is None:
     __package__ = "pythonlib.ensemble"
     import pythonlib

After that is done, this should work: 完成之后,这应该可以工作:

from ..verification import obs

It's a hacky solution that would work but is generally discouraged. 这是一个哈克的解决方案,将工作,但一般不提倡。

You can modify python path in place when you have to omit conflicts. 当您必须省略冲突时,可以在适当位置修改python路径。 Like that: 像那样:

import sys  # needed to make it work

tmp = sys.path[0]
sys.path = sys.path[1:]  # ugly and hacky thingy

# import stuff you need (would work with __init__.py in a base dir)
from python_lib import verification
from ..verification.obs import obs

# fix path back
sys.path.insert(0, tmp)

I just tested this pattern and it seems to work (Python 3.6.0) 我刚刚测试了这种模式,它似乎可以工作(Python 3.6.0)

There are some rules that has to be followed while creating packages and modules. 创建包和模块时必须遵循一些规则。

  1. Make sure there is __init__.py file as a part of your package. 确保软件包中包含__init__.py文件。 Every python package is expected to have this file 每个python包都应该有这个文件
  2. While the module is looked it happens in 3 ways. 在查看模块时,它以3种方式发生。

A very good documentation is available Module-search-path 提供了很好的文档Module-search-path

Usually while building projects it a practice to create a lib package and add sub directories based on different categories and add the main directory to the PYTHONPATH variable. 通常,在构建项目时,一种做法是创建一个lib包,并根据不同的类别添加子目录,并将主目录添加到PYTHONPATH变量中。 This make the module available for other programs. 这使该模块可用于其他程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM