Python 导入、路径、目录和模块

标签 python module package

首先让我说,我在过去一周进行了广泛的研究,但尚未找到这些问题的实际答案 - 只是一些模糊的答案,无法真正解释正在发生的事情。如果那只是因为我错过了我要找的东西,我很抱歉 - 请指出正确的方向。

我的目录结构是:

TestProject/
    runtest*
    testpackage/
        __init__.py
        testmod.py
        testmod2.py
        testsubs/
            testsubmod.py

一些注意事项:

  • 我在 Ubuntu 上使用 python2.7
  • 我正在使用 bpython 进行测试
  • 我正在从特定目录运行 bpython 以测试导入行为的方式
  • 我正在努力遵循最佳实践。
  • 这个包没有安装,它在一个随机的开发目录中
  • 这个目录不在python路径中
  • 我在包目录中有一个init.py
  • 嵌套目录中没有init.py文件
  • init.py 文件为空
  • testpackage/testmod.py 包含 TestModClass
  • testpackage/testsubs/testsubmod.py 包含 TestSubModClass

我观察到的事情:

  • 当我从 TestProject 运行 bpython 时,import testpackage 有效
    • 这不会导入 testpackage.testmod
    • 我根本无法访问 testpackage.testmod
  • 当我从 TestProject/import testpackage.testmod 运行 bpython 时失败
  • 当我从 TestProject/from testpackage import testmod 运行 bpython 时
  • 我可以将代码添加到 init.py 以显式导入 testmod.py,而不是 testsubs/testmod.py
    • 我认为这不是正确的方法,如果用户不想导入该模块怎么办?
  • 我可以从 testmod.py 导入 testmod2,但不能导入 testpackage.testmod2
    • 这样做会很好,这样我就可以用与 STL 或扭曲名称重叠的名称(例如 testpackage.logging)命名我自己的模块,而不会导致错误(不得不将我自己的模块命名为 customerlogging 之类的废话,而不是只是 mypackage.logging)

还有问题:

  1. python 对存在于 pythonpath 中的包和模块的导入处理方式是否与您尝试从当前目录导入时不同?
  2. 为什么 import testpackage 不给我访问 testpackage.testmod 的权限?当我导入 os 时,我可以访问 os.path(等)。
  3. 对于包,我应该坚持在基本目录中使用单个 init.py,还是应该将它们嵌套在后续目录中?
  4. 如何导入指定包名称的模块? IE。从 testmod.py,我想导入 testpackage.testmod2 而不仅仅是 testmod2。
  5. 从 subsubs 目录导入子模块的正确方法是什么?
    1. 我看到的唯一解决方案是将该目录附加到 init.py 的 pythonpath,但我不知道这是否是正确的方法。

提前致谢。

最佳答案

首先,您会在section 6 of The Python Tutorial 中找到您需要的所有信息。 .


(1) Does python deal differently with imports on packages & modules that exist in the pythonpath than when you are trying to import from your current directory?

不,它没有。实际上,Python 在导入模块时总是搜索 sys.path。当前目录中的模块只能找到,因为 sys.path 包含一个带有空字符串的条目,表示当前目录。


(2) Why doesn't import testpackage give me access to testpackage.testmod? When I import os, I can then access os.path (etc).

为了效率,import testpackage只加载testpackage/__init__.py。如果您需要 testpackage.testmod,您必须显式导入它:

import testpackage   # Just imports testpackage, not testpackage.testmod!
import testpackage.testmod   # Import *both* testpackage and testpackage.testmod!

如果你总是想导出testmod,在__init__.py中导入它,这就是os (os/__init__ .py) 会。这样,如果您导入 testpackagetestpackage.testmod 始终隐式可用。

由于 Python 是跨平台的,实际上没有办法始终如一地自动加载目录中的模块,因为某些文件系统不区分大小写(Windows!)。 Python 不知道是否将 os/path.py 加载为 os.pathos.Path


(3) With a package, should I stick to using a single __init__.py in the base directory, or should I be nesting them in subsequent directories?

对于每个子包,您总是需要一个 __init__.py。曾就取消此要求进行过讨论,但最终决定保持原样。


(4) How can I import a module specifying the package name? I.E. from testmod.py, I would like to import testpackage.testmod2 rather than just testmod2.

这应该有效。只需确保从顶级目录运行代码即可。如果当前目录是 testpackagetestmod 不知道它在包中。

不过,首选方法是使用相对包内导入:

from . import testmod2

如果有一个名为 testmod2 的全局模块,这可以防止名称冲突,并使您能够毫无问题地在包中使用众所周知的模块的名称。


(5) What is the proper way to import submodules from the subsubs directory? The only solution I see is to append that directory to the pythonpath from __init__.py, but I don't know if that's the correct way.

不,不要那样做!永远不要将一个目录放到 sys.path 中,而当它的父目录之一已经在 sys.path 中时!这可能会导致您的模块被加载两次,这是一件坏事!

通常你应该能够使用绝对或相对导入从子包中加载模块:

import testpackage.testsubs.testsubmod
from testpackage.testsubs import testsubmod
from .testsubs import testsubmod

只需确保在 testsubs/ 中创建一个 __init__.py!

关于Python 导入、路径、目录和模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7163204/

相关文章:

java - 如何在Eclipse的Gradle项目中重命名包

python - 有没有办法在 Windows 上使用 gradle 编译 python protobuf?

module - 在 OCaml 顶层使用 Str 模块?

Python `__init__.py` 和代码中对象的初始化

r - 如何使用 xlsx(R 包)设置特定单元格的值?

linux - 如何为 debian non-free 创建离线存储库?

Python 特征值和特征向量

python - 如何删除和移动 pandas df 列中的值

python - 如何从命令行使包可执行?

javascript - 如何使用 namespace 导入而不导入所有内容?