添加彼此依赖的python模块作为git子模块

时间:2016-03-08 04:27:24

标签: python git python-3.x module git-submodules

我在2个独立的git存储库中有这两个小模块:

RepoA/A.py

def foo():
    return "Hello World"

RepoB/B.py

import sys
try:
    import A
except ImportError:
    print("Dependency not available!")
    sys.exit(1)

def bar():
    return A.foo() + " EXTENDED!"

您看到B当前假设A可全局导入(已安装或在脚本执行目录中)。

两个根目录都有一个空__init__py,可以将它们作为子模块导入。

现在我有另一个需要B的更大的存储库C.它既有A又有B作为git子模块,所以结构实际上是这样的:

RepoC
|---utils/
|   |---__init__.py
|   |---RepoA/
|   |   |---__init__.py
|   |   |---A.py
|   |---RepoB/
|       |---__init__.py
|       |---B.py
|---C.py

RepoC/C.py

import utils.B

print(B.bar())

RepoC/utils/__init__.py

# remove the 1-layer indirection through the submodule
from .RepoB import B

现在按预期打印Dependency not available!,因为A不是全局可用的,而是位于B的地方永远无法猜测(在这种情况下,它需要from ..RepoA import A A 1}})。如果我通过将sys.path添加到RepoC/utils/__init__.py再次使全局可用,则可以使用它:

import os, sys import inspect def fake_install(module_path): # the submitted module path is relative to the caller's location # therefore get that script's file location first caller_module = inspect.getmodule(inspect.stack()[1][0]) caller_dir = caller_module.__file__.rsplit(os.path.sep, 1)[0] # build an absolute file path and append it to the system paths path = os.path.join(os.path.abspath(caller_dir), *module_path.split(".")) sys.path.append(path) fake_install("RepoA") # remove the 1-layer indirection through the submodule from .RepoB import B

<div class="popular">
   <h3>POPULAR FISH TANK AQUARIUM</h3>
   <div>
   <img src="http://s16.postimg.org/xgo1837a9/image.png" alt="" />
   <img src="http://s16.postimg.org/xgo1837a9/image.png" alt="" />
   <img src="http://s16.postimg.org/xgo1837a9/image.png" alt="" />
   <img src="http://s16.postimg.org/xgo1837a9/image.png" alt="" />
   <img src="http://s16.postimg.org/xgo1837a9/image.png" alt="" />
   <img src="http://s16.postimg.org/xgo1837a9/image.png" alt="" />
   <img src="http://s16.postimg.org/xgo1837a9/image.png" alt="" />
   <img src="http://s16.postimg.org/xgo1837a9/image.png" alt="" />
   <img src="http://s16.postimg.org/xgo1837a9/image.png" alt="" />
   </div>
   </div>

这感觉就像是一个可怕的解决方案。

另一个想法是根本不使用git子模块,而只是在requirements.txt中收集依赖关系作为git-links,编写一些setup.exe脚本并让pip 实际安装它们。

我怎样才能优雅地克服这个问题?是否有任何导入技巧可以让我这样做?

2 个答案:

答案 0 :(得分:2)

正如您可能已经猜到的那样,我认为您有两种选择:要么让A和B成为C的一部分,要么制作B和C独立包。

pip的工作是将#A;放在sys.path&#34;中的某个地方,所以你不妨让他这样做而不是自己动手。你可以在需求中使用git链接,但不能在setup.py中使用git链接,所以如果你有更多的依赖关系(D需要B需要C)并且你不能在PyPI上发布它们你可能需要私有PyPI服务器(devpi适用于此)。

答案 1 :(得分:1)

(我自己想通了)
这可以通过删除子模块存储库文件夹引入的额外间接来解决。您需要__init__.pyRepoA中当前为空的Repo个文件作为其包含模块(此处为utils),以便RepoC能够设置相关性那里有。

修改您的RepoB/__init__.py,如下所示:

from .. import *

然后通过将这些依赖项A添加到utils&#39;中来使您的依赖项__init__.py可用。 from .RepoA import A

B.py

现在您需要做的就是在from . import A local:

中进行导入
try:
    from . import A
except ImportError:
    import A

您也可以将其作为全局依赖项工作:

__init__.py

现在所有图书馆用户必须做的是:

  • 全局安装依赖项,或
  • 在包含模块中使相关性可用

为了使这种方法更加通用,我将拥有子模块中的所有RepoA/__init__.py&#39;根目录就像这样的桥梁:

from .. import * __all__ = ["A"]

RepoB/__init__.py

from .. import * __all__ = ["B"]

utils/__init__.py

并做同样的事情,即从另一方面去除间接&#34;&#34;。在这种情况下,from .RepoA import * from .RepoB import *

String url = "jdbc:mysql://localhost:3306/Pokedex";