我在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 实际安装它们。
我怎样才能优雅地克服这个问题?是否有任何导入技巧可以让我这样做?
答案 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__.py
和RepoA
中当前为空的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";