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

nfa*_*rar 6 python module package

首先让我说我已经对过去一周的过程进行了广泛的研究,但还没有找到这些问题的实际答案 - 只是一些模糊的答案并没有真正解释正在发生的事情.如果这只是因为我错过了我想要的东西,我很抱歉 - 请指出我正确的方向.

我的目录结构是:

TestProject/
    runtest*
    testpackage/
        __init__.py
        testmod.py
        testmod2.py
        testsubs/
            testsubmod.py
Run Code Online (Sandbox Code Playgroud)

几个笔记:

  • 我在Ubuntu上使用python2.7
  • 我正在测试bpython
  • 我正在从特定目录运行bpython来测试导入行为的方式
  • 我正在尝试遵循最佳做法.
  • 这个软件包没有安装,它在一个随机的dev目录中
  • 该目录不在pythonpath中
  • 我在包目录中有一个init .py
  • 嵌套目录中没有init .py文件
  • 初始化 .py文件是空的
  • testpackage/testmod.py包含TestModClass
  • testpackage/testsubs/testsubmod.py包含TestSubModClass

我观察到的事情:

  • 当我从TestProject /运行bpython 进口testpackage作品
    • 这不会导入testpackage.testmod
    • 我根本无法访问testpackage.testmod
  • 当我从TestProject/import运行bpython时,testpackage.testmod失败了
  • 当我从testProject运行bpython/从testpackage导入testmod工作
  • 我可以向init .py 添加代码以显式导入testmod.py,但不能testubs/testmod.py
    • 我不认为这是正确的方法,如果用户不想导入该模块怎么办?
  • 从testmod.py我可以导入testmod2,但不能导入testpackage.testmod2
    • 这样做很好,我可以使用STL或扭曲的名称(例如testpackage.logging)命名我自己的模块,而不会导致错误(很糟糕的是必须命名我自己的模块废话,如customerlogging,而不仅仅是mypackage.日志记录)

问题是:

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

提前致谢.

Fer*_*yer 8

首先,您将在The Python Tutorial的第6部分找到所需的所有信息.


(1)python路径中存在的包和模块上的python与您尝试从当前目录导入时的处理方式不同吗?

不,它没有.实际上,Python总是sys.path在导入模块时进行搜索.仅找到当前目录中的模块,因为sys.path包含带有空字符串的条目,即当前目录.


(2)为什么不import testpackage给我访问testpackage.testmod?当我导入时os,我可以访问os.path(等).

为了提高效率,import testpackage只需加载testpackage/__init__.py.如果需要testpackage.testmod,您必须明确导入它:

import testpackage   # Just imports testpackage, not testpackage.testmod!
import testpackage.testmod   # Import *both* testpackage and testpackage.testmod!
Run Code Online (Sandbox Code Playgroud)

如果你总是想导出testmod,导入它__init__.py,这就是os(os/__init__.py)的作用.这样,testpackage.testmod如果您导入,则始终隐含可用testpackage.

由于Python是跨平台的,因此实际上无法在目录中一致地自动加载模块,因为某些文件系统不区分大小写(Windows!).Python不知道是否加载os/path.pyos.pathos.Path等.


(3)使用包,我应该坚持__init__.py在基本目录中使用单个,还是应该将它们嵌套在后续目录中?

__init__.py每个子包都需要一个.有关于放弃这一要求的讨论,但决定保持原样.


(4)如何导入指定包名称的模块?IE来自testmod.py,我想导入testpackage.testmod2而不仅仅是testmod2.

这应该工作.只需确保从顶级目录运行代码.如果当前目录是testpackage,testmod则不知道它在包中.

但首选的方法是使用相对的包内导入:

from . import testmod2
Run Code Online (Sandbox Code Playgroud)

如果存在名为的全局模块testmod2,则可以防止名称冲突,并使您可以使用包中的已知模块的名称而不会出现问题.


(5)从subsubs目录导入子模块的正确方法是什么?我看到的唯一解决方案是将该目录附加到pythonpath __init__.py,但我不知道这是否正确.

不,不要那样做!从来没有把目录放在sys.path其中一个父目录已经存在的时候sys.path!这可能导致您的模块加载两次,这是一件坏事!

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

import testpackage.testsubs.testsubmod
from testpackage.testsubs import testsubmod
from .testsubs import testsubmod
Run Code Online (Sandbox Code Playgroud)

只要确保创建一个__init__.py内部testsubs/!


Tho*_*asH 0

  1. 不会。当前目录只是添加到 PYTHONPATH 中。
  2. 首先,你需要一个 __init__.py 。其次,os.path 出现是因为 os 正在导入 os.path。
  3. 您需要在每个目录中以及包含该目录的目录中都有一个 __init__.py testpackage
  4. 在包的 __init__.py 中,导入您希望提供的模块。
  5. 从 sub1.sub2 导入子模块
    1. 不,如果最顶层目录位于 PYTHONPATH 上,并且该目录和子目录都有其 __init__.py,则这就是您需要从任何子目录导入的全部内容。