【问题标题】:Python best practice import submodule in submodulePython 最佳实践在子模块中导入子模块
【发布时间】:2021-02-03 17:42:25
【问题描述】:

我目前正在阅读有关子模块导入中 Python 的子模块的信息,但不知何故我找不到正确的答案。这是一个例子:

root/
     main.py
     moduleA/
             __init__.py
             log.py
     moduleB/
             __init__.py
             worker.py

我想使用import moduleA.loglog 导入worker。我想在main 中导入worker 并在那里使用它。

到目前为止,我已经找到了以下解决方案:

  • sys.path 附加到../ (sys.path.append('../'))
  • 我阅读了一些关于使用 pip -e 将我的模块安装到环境中的内容。
  • 避免从子模块导入的脚本。

我听说sys.path hack 被认为是最佳实践。但不知何故感觉不对。

所以我想知道你认为什么是最佳实践。

【问题讨论】:

    标签: python python-module


    【解决方案1】:

    你可以使用相对导入来解决这个问题:

    main.py

    from .moduleB import worker
    

    worker.py:

    from ..moduleA import log
    

    一个点将当前目录作为路径的开头,因此.moduleB 挖掘到当前目录下的文件夹moduleB
    两个点向上移动一个目录,所以..moduleA in 上升到root 目录,然后下降到moduleA。每个额外的点都是一个目录。
    F.I. from . import ab 将从同一目录导入 ab.py
    打包/安装模块不需要进行相对导入。但是你必须使用from ..moduleA import log 导入。使用 import ..moduleA.log 导入将不适用于相对导入。

    【讨论】:

      【解决方案2】:

      我通常会使用包含所有导入的 modulename.py 文件,稍后我可以参考:

      你的结构:

      root/
           __init__.py
           root.py
           modulea/
               __init__.py
               a.py
            moduleb/
               __init__.py
               b.py
      

      root.py 将是:

      from modulea.a import sleep, eat, breath
      from moduleb.b import read, write, watch
      

      这样我以后可以做

      from package.root import sleep, read, watch
      

      但是,这需要安装您的软件包,这可能并不总是可行的。

      【讨论】:

        【解决方案3】:

        我个人更喜欢更改我当前的工作目录并导入以防万一我遇到这个问题。

        root/
             __init__.py
             root.py
             modulea/
                     __init__.py
                     a.py
             moduleb/
                     __init__.py
                     b.py
        

        鉴于这样的设置,

        a.py
        def a():
            print("i am a")
        

        在 b 中,只需通过os.chdir 使用绝对或相对路径将当前目录更改为根目录

        b.py
        
        def b():
            print("i am b")
        
        import os
        os.chdir('..')
        from modulea.a import a
        a()
        

        运行 b.py 打印 i am a

        还有其他选项,sys.path 或 PYTHONPATH 修改。 Refer here

        不过,我也建议您尽可能避免此类情况。

        【讨论】:

          猜你喜欢
          • 2015-02-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-10
          • 2012-05-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多