具有公共包层次结构的模块可以在我的 PYTHONPATH 中多次提及吗?

发布于 2024-12-01 05:31:06 字数 807 浏览 4 评论 0原文

我有两个共享包名称的独立项目。只要它们不在 PYTHONPATH 上,它们就可以正常运行,但是一旦它们都出现,其中一个就无法在自己的项目中找到导入。

例如,像这样的两个项目:

项目 1:

x/
  __init__.py
  test.py
  foo.py

test.py 包含行:

import x.foo

项目 2:

x/
  __init__.py
  bar.py

如果我运行,

PYTHONPATH=. python x/y/test.py

则没有错误。但是如果我运行

PYTHONPATH='pathtoproject2:.' python x/test.py

我会收到错误:

Traceback (most recent call last):
  File "x/test.py", line 1, in <module>
    import x.foo
ImportError: No module named foo

有没有办法让具有公共包的不同 Python 项目共享 PYTHONPATH?或者Python将始终只使用找到包的第一个路径?

注意:我知道如果您将 import from x.foo 修改为 import foo 那么它就会起作用。但我想知道是否可以在不修改任何一个包的情况下做到这一点。

I have two separate projects that share a package name. They run OK as long as they are not both on the PYTHONPATH, but as soon as they both appear one of them cannot find imports in its own project.

Example, two projects like this:

Project 1:

x/
  __init__.py
  test.py
  foo.py

test.py contains the line:

import x.foo

Project 2:

x/
  __init__.py
  bar.py

If I run

PYTHONPATH=. python x/y/test.py

there is no error. But if I run

PYTHONPATH='pathtoproject2:.' python x/test.py

I get the error:

Traceback (most recent call last):
  File "x/test.py", line 1, in <module>
    import x.foo
ImportError: No module named foo

Is there a way to have different Python projects with a common package share the PYTHONPATH? Or will Python always use only the first path where a package is found?

Note: I know if you modify the import from x.foo to import foo then it will work. But I want to know if it is possible to do it without modifying either package.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怪我鬧 2024-12-08 05:31:06

尽管导入机制本身不支持,但有一个解决方案可以在 python 中创建命名空间包。您只需将以下代码放在两个 __init__.py 文件中即可。

try:
    import pkg_resources
    pkg_resources.declare_namespace(__name__)
except ImportError:
    import pkgutil
    __path__ = pkgutil.extend_path(__path__, __name__)

pkg_resources 由 setuptools python 包提供,其优点是还可以处理 Egg zip 文件中包含的包。

pkgutil 包含在 python 的标准库中,因此如果系统中未安装 setuptools,我们将依赖它来处理命名空间扩展。

有关 python 命名空间包的更多信息,请访问:

http://packages.python .org/distribute/setuptools.html#namespace-packages

http://www.python.org/dev/peps/pep-0382/

Although not supported natively by the import mechanism, there is a workaround solution to create namespaced packages in python. You just have to put the following code on both __init__.py files.

try:
    import pkg_resources
    pkg_resources.declare_namespace(__name__)
except ImportError:
    import pkgutil
    __path__ = pkgutil.extend_path(__path__, __name__)

pkg_resources is provided by setuptools python package and has the advantage that also handles packages contained within egg zip files.

pkgutil is contained in python's standard library so we rely on it to handle the namespace extension if setuptools is not installed in the system.

for more information about python namespace packages can be found here:

http://packages.python.org/distribute/setuptools.html#namespace-packages

http://www.python.org/dev/peps/pep-0382/

何以笙箫默 2024-12-08 05:31:06

目前,Python 不支持来自不同目录的包。包是一个单元,而不仅仅是一个命名空间。这与 Java“包”或更恰当地称为 .NET 中的“命名空间”不同。

导入包时,Python 将按顺序扫描 sys.path,并使用第一个匹配项。如果路径后面出现的目录中有另一个具有匹配名称的模块或包,则不会找到它。

顺便说一句,你的“笔记”不是真的。当您使用 import foo 时,Python 将在 test.py 目录中尝试相对导入,找不到匹配项,然后尝试绝对导入模块 foo< /code>,它也不存在,然后引发 ImportError

不要使用包名称来使用公共前缀对模块进行分组,而是将包视为小型的独立库。在Python中,扁平比嵌套更好,拥有多个顶级包(每个包实现一个不同的目的)比拥有一个大型单片包更好。只需使用 foobar,而不是 org.example.fooorg.example.bar

Currently, Python does not support packages from different directories. A package is an unit, not just a namespace. This is different from Java "packages" or the more appropriately named "namespaces" in .NET.

When importing a package, Python will scan sys.path, sequentially, and use the first match. If there is another module or package with a matching name in a directory that appears later in the path, it won't be found.

Your "note" is not true, by the way. When you use import foo, Python will try a relative import within the directory of test.py, find no match, then attempt an absolute import of module foo, which does not exist either, and then raise an ImportError.

Instead of using package names to group modules using a common prefix, think of packages as smallish, self-contained libraries. In Python, flat is better than nested, and it is preferable to have multiple top-level packages, each fulfilling one distinct purpose, than having one large monolithic package. Instead of org.example.foo and org.example.bar, just use foo and bar.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文