- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个像这样的包布局
myproject/
setup.py # contains package info for "myproject" package
myproject/ # contains various Python source files
deploy/ # contains non-package Python scripts for deployment tools
tests/
...
如果我发出 pip install -e .
(这是在 conda 环境中),则从顶级 myproject
文件夹内部,则路径 /path/to/myproject
最终始终成为 sys.path
的一部分。
例如,如果我创建 myproject
存储库的新克隆并将其存储在新文件夹中,例如 myproject2
,那么,然后在交互式环境中执行一些工作在该文件夹中的解释器中,我发现 sys.path
在启动时仍然会自动具有 /path/to/myproject
。
我的预感是这种情况正在发生,因为 pip install -e
会将文件从 /path/to/myproject
符号链接(symbolic link)到 site-packages
或其他合适的位置,Python 中的模块系统初始化必须做一些特殊处理,它遵循符号链接(symbolic link)并自动将源目录添加到路径中。
我遇到的问题是 deploy/
中的(非包)脚本使用绝对导入来引用同一文件夹中的其他脚本(因为它们旨在从顶层执行) myproject
),如何防止 Python 只查找使用 pip install -e< 的
从而出现在 Python 路径上?myproject
的特定克隆存在的此文件夹的副本
已添加
在这种情况下,命名空间包会发生什么,这也让我感到困惑。例如,如果 deploy/
文件夹没有 __init__.py
文件,但您正在执行 /path/to/myproject
中的内容> 工作目录(或者在 Python 路径中),那么在 Python 3.3+ 中它将被视为可以跨目录的命名空间包。
如果我两者都有会发生什么
/path/to/myproject # which has been installed with pip install -e
/path/to/myproject2 # not installed, extra clone of the same project
然后,如果我在 /path/to/myproject2
中处理 deploy/
脚本,它们最终是否会被视为还包含 /path/to/myproject/deploy/
因为 /path/to/myproject
凭借 pip install -e
始终位于 Python 路径中?
那么最后一个问题是,这会对意外跨越两个目录的“大型”deploy
命名空间包内的绝对导入和相对导入以及导入优先级产生什么影响。
最佳答案
这是 easy-install.pth
site-packages
目录中的文件对 sys.path
的值有影响。此效果不依赖于当前工作目录。我仍然不完全确定 *.egg-link
到底扮演什么角色文件在 site-packages
目录中播放(尽管它确实意味着(至少部分地)作为符号链接(symbolic link)的独立于平台的替代品)。
至于命名空间包...让我们考虑以下目录树:
.
├── alfa
│ ├── bravo
│ │ ├── one.py
│ │ └── zero.py
│ └── zero.py
├── foo
│ ├── bar
│ │ ├── two.py
│ │ └── zero.py
│ └── zero.py
└── src
├── alfa
│ ├── bravo
│ │ ├── three.py
│ │ └── zero.py
│ └── zero.py
└── foo
├── bar
│ ├── four.py
│ └── zero.py
├── __init__.py
└── zero.py
所有*.py
文件包含以下内容:
print(__name__, __file__)
请注意,只有一个包初始值设定项 src/foo/__init__.py
。
模块 alfa.bravo.one
和 foo.bar.two
是可导入的,因为当前目录始终位于 Python 解释器的搜索路径上(sys.路径
):
$ python3 -c 'import alfa.bravo.one'
alfa.bravo.one /home/sinoroc/workspace/so-59682278/alfa/bravo/one.py
$ python3 -c 'import foo.bar.two'
foo.bar.two /home/sinoroc/workspace/so-59682278/foo/bar/two.py
但是导入 alfa.bravo.third
和 foo.bar.four
是不可能的:
$ python3 -c 'import alfa.bravo.three'
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'alfa.bravo.three'
$ python3 -c 'import foo.bar.four'
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'foo.bar.four'
出现这种情况是因为它们位于 src
目录中,而该目录不在 Python 的路径上:
$ python3 -c 'import sys; print(sys.path)'
['', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload', '/home/sinoroc/workspace/so-59682278/.venv/lib/python3.6/site-packages']
可以通过将目录位置写入解释器的 site-packages
目录中的 .pth
中,将目录添加到 Python 路径中:
$ echo "${PWD}/src" > '.venv/lib/python3.6/site-packages/test.pth'
$ python3 -c 'import sys; print(sys.path)'
['', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload', '/home/sinoroc/workspace/so-59682278/.venv/lib/python3.6/site-packages', '/home/sinoroc/workspace/so-59682278/src']
现在可以导入 alfa.bravo.third
和 foo.bar.four
:
$ python3 -c 'import alfa.bravo.three'
alfa.bravo.three /home/sinoroc/workspace/so-59682278/src/alfa/bravo/three.py
$ python3 -c 'import foo.bar.four'
foo /home/sinoroc/workspace/so-59682278/src/foo/__init__.py
foo.bar.four /home/sinoroc/workspace/so-59682278/src/foo/bar/four.py
由于命名空间包的存在,模块 alfa.bravo.one
仍然可以导入:
$ python3 -c 'import alfa.bravo.one'
alfa.bravo.one /home/sinoroc/workspace/so-59682278/alfa/bravo/one.py
但是由于 src
目录中的包 foo
有一个初始化程序,foo
不再是命名空间包,并且模块 foo.bar.two
无法导入:
$ python3 -c 'import foo.bar.two'
foo /home/sinoroc/workspace/so-59682278/src/foo/__init__.py
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'foo.bar.two'
现在对于zero
模块来说有 pip 令人惊讶。当前目录和 src 目录中都有具有完全相同导入路径的模块:
$ python3 -c 'import alfa.zero'
alfa.zero /home/sinoroc/workspace/so-59682278/alfa/zero.py
$ python3 -c 'import alfa.bravo.zero'
alfa.bravo.zero /home/sinoroc/workspace/so-59682278/alfa/bravo/zero.py
$ python3 -c 'import foo.zero'
foo /home/sinoroc/workspace/so-59682278/src/foo/__init__.py
foo.zero /home/sinoroc/workspace/so-59682278/src/foo/zero.py
$ python3 -c 'import foo.bar.zero'
foo /home/sinoroc/workspace/so-59682278/src/foo/__init__.py
foo.bar.zero /home/sinoroc/workspace/so-59682278/src/foo/bar/zero.py
如果没有初始化的包(alfa
),则导入当前工作目录中的版本。但如果有一个版本带有初始化程序 (foo
),那么这就是导入的已初始化包中的版本。
注释
关于python - pip install -e,Python 路径和命名空间包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59682278/
我是 Maven 新手,正在尝试了解它是如何工作的。 我知道生命周期由多个阶段组成。阶段称为他们的魔力。如果调用一个阶段,则前面的所有阶段也会执行。例如,当我调用 mvn install 时就会发生这
我想安装Ros(机器人操作系统)的驱动程序,我有两个选项:二进制安装和从源代码编译安装。我想知道哪种安装更好,每种安装有哪些优点和缺点。 最佳答案 源:又称源代码,通常位于某种 tarball 或 z
以及更具体的问题。我的理解对吗: “nuget install”总是安装到您运行它的目录吗? “choco install”安装到特殊的 choco 目录,然后运行脚本在系统中传播它? “nuget
我创建了 Android 项目,但随后我立即得到出现错误的信息。 Warning:(22, 12) Dependency on a support library, but the SDK insta
我的安装程序有 32 位和 64 位版本,它们具有(几乎)完全相同的代码和自定义操作序列(只有与此问题无关的细微差别) 我希望我的安装程序能够检测它之前是否已安装,并在这种情况下运行我自己的代码,而不
我在TFS版本中使用npm install cmd。我总是得到以下警告: npm WARN optional dep failed, continuing fsevents@0.3.1 如何删除此警告
是否可以将install(TARGETS ...)与在add_subdirectory添加的目录中定义的目标一起使用? 我的用例是,我想为gtest构建一个rpm的e.gg。 gtest项目恰好有一个
我需要使用 MSI 创建安装程序,其目的是根据用户的区域(从环境变量读取)调用正确的安装程序。也就是说,这个安装程序应该有 3 个文件(它们本身就是安装程序),一个用于美国,一个用于欧洲,一个用于亚洲
我正在尝试通过 Android Studio 3.5 在我的小米 RedMi S2 上运行我的应用程序。在手机上安装应用程序时抛出错误: Installation did not succeed. T
使用govendor时,go install、govendor install +local和govendor install +vendor,^program有什么区别? govendor inst
我用谷歌搜索了很多,但找不到答案。因此,在 Windows Installer 属性值中可以存储多少个字符。如果你给出答案,你能提供答案的来源吗? 最佳答案 我问 Windows Installer
Cuda v9.0 有几个补丁 我应该安装最新补丁还是安装所有补丁? https://developer.nvidia.com/cuda-90-download-archive?target_os=W
我正在尝试通过它的文档安装 phalcon!在这一步我有一个错误: installation/FreeBSD Command: pkg_add -r phalcon 错误: 'pkg_add' is
我有一个安装,如果应用程序退出,它会升级该应用程序的先前版本。当安装处于升级模式时,我想跳过某些操作。如何确定安装是在升级模式还是首次安装模式下运行? 我正在使用 Wise Installer,但我认
MSI 数据库包含一个表 MsiFileHash 。根据文档MsiFileHash 表用于存储 Windows Installer 包提供的源文件的 128 位哈希。 有人知道使用/应该使用什么哈希算
我尝试在本地和全局运行 npm install browserify (-g) 但我总是遇到以下错误 npm ERR! peerinvalid The package bn.js does not s
我有一个用于我正在构建的 python 模块的 SConstruct 文件: import distutils.sysconfig env = Environment(CPPPATH=['includ
使用 Installshield 2010 和 Basic MSI 项目。 我有一个之前由我的安装程序安装的 exe。该 exe 需要在安装程序升级期间运行。有没有办法保证安装程序不会尝试关闭进程?基
我是围棋初学者。我试图编译一个 go 项目,但找不到任何解释“/...”的文档或文章。 cd ~/src/ephenation-server go install -v ./... 等待您的帮助。 最
我试过在选择和不选择‘安装Mongo指南针’选项的情况下运行安装程序,但我仍然无法安装它,也无法取消安装。然后,此设置对话冻结20-30分钟以上,没有任何进展。这实际上就是从他们的website(ht
我是一名优秀的程序员,十分优秀!