是否可以使用两个具有相同名称的 Python 包?
问题描述
我有一个关于进口的问题.这个问题可能看起来有点做作,但它的目的是探索对包中的所有导入使用绝对导入的限制.PEP8 强烈反对相对导入(和 Google Python 风格指南 说永远不要使用它们).
假设您有两个同名的大型软件包,并且都使用符合 PEP8 的绝对导入:
<上一页>/pkg1mod1.py(包含绝对导入:'import pkg1.mod2')模组2.py.../pkg1mod1.py(包含绝对导入:'import pkg1.mod3')模组3.py...另外说你正在处理一个 Python 项目,你想在其中使用这两个包.例如,如果您想在一个项目中使用同一包的两个版本,则可能会出现这种情况.
有没有办法将这两个包合并到您的项目层次结构中,以便您可以在整个项目中自由使用这两个包中的模块?
对于解决方案,可以使用导入别名和临时修改 sys.path 之类的操作.但是不可以随便改动一个包目录的内容.
解决方案简短的回答是否定的,Python 不接受两个同名的包.(有些东西称为命名空间包",它允许在多个目录中实现单个包,但它们需要设置所涉及的包以相互协作.
PEP 8 不鼓励显式相对导入的方式是其更值得怀疑的建议之一,正是因为它使得重命名包以避免命名冲突变得更加困难.如果这两个包使用相对导入,您可以重命名其中一个或将其嵌套在另一个包中并完成.
import aliases 在这里对您没有帮助,因为重要的是以 sys.modules
结尾的名称,并且它使用导入的模块名称,而不是最终被绑定在导入模块中.
如果你想获得真正的异国情调,你可以编写自己的导入器(参见 PEP 302 和 3.x importlib
文档).如果你决定走那么远,你几乎可以做任何你想做的事情.
I have a question about imports. The question might seem a bit contrived, but its purpose is to explore the limitations of using absolute imports for all imports in a package. PEP8 highly discourages relative imports (edit: and the Google Python Style Guide says never to use them).
Say you are given two large-ish packages that both have the same name and that both use absolute imports in accordance with PEP8:
/pkg1 mod1.py (contains an absolute import: 'import pkg1.mod2') mod2.py ... /pkg1 mod1.py (contains an absolute import: 'import pkg1.mod3') mod3.py ...
Also say you are working on a Python project in which you'd like to use both packages. This could come up, say, if you want to use two versions of the same package in a project.
Is there a way to incorporate both packages into your project hierarchy so that you can freely use modules from both packages throughout your project?
For the solution it's acceptable to do things like use import aliases and modify sys.path temporarily. But it's not okay to change the contents of either package directory.
解决方案The short answer is no, Python doesn't accept two packages with the same name. (There are things called "namespace packages" that let a single package be implemented over multiple directories but they require the packages involved to be set up to cooperate with each other).
The way PEP 8 discourages explicit relative imports is one of its more questionable pieces of advice, precisely because it makes it harder to rename a package to avoid naming conflicts. If the two packages used relative imports, you could just rename one of them or nest it inside another package and be done with it.
import aliases won't help you here, because it is the name that ends up in sys.modules
that matters, and that uses the name of the module as imported, rather than the name that ends up being bound in the importing module.
If you wanted to get really exotic, you could write your own importer (see PEP 302 and the 3.x importlib
documentation). If you decide to go that far, you can do pretty much anything you want.
相关文章