当执行我的 python 项目中的脚本时,如何将路径添加到 $PYTHONPATH 或 $PATH 变量?
How can I add paths to the $PYTHONPATH or $PATH variables when a script within my python project is executed?
我有一个包含多个脚本(scriptA、scriptB、scriptC)的 python 项目,这些脚本必须能够找到位于项目子路径中的不是 python 包或模块的包。组织是这样的:
|_project
|_scriptA.py
|_scriptB.py
|_scriptC.py
|_thrift_packages
|_gen-py
|_thriftA
|__init__.py
|_thriftA.py
在每个脚本的基础上,我将此目录的绝对路径添加到 sys.path
每次在项目中执行脚本时,我是否可以更改 PYTHONPATH 或 sys.path,这样我就不必将此目录的路径附加到 sys.path每个脚本的基础?
你应该在每个包中添加__init__.py
,然后正确调用你所有的脚本。
|_project
|_scriptA.py
|_scriptB.py
|_scriptC.py
|__init__.py <====== Here
|_thrift_packages
|__init__.py <====== Here
|_gen-py
|_thriftA
|__init__.py
|_thriftA.py
假设 project
在你的 pythonpath 中,你可以这样做:
from project.thrift_packages.thriftA import thriftA
是的,你可以。
但是我认为其他答案更适合您当前的问题。
这里我只是解释一下,如何调用另一个环境,另一个当前工作目录的子进程。
这在其他情况下可以派上用场。
您可以将当前环境作为字典获取 (os.environ),将其复制到另一个字典,对其进行修改并将其传递给 supbprocess 调用。 (子流程函数有一个 env 参数)
import os
import subprocess
new_env = dict(os.environ)
new_env["PYTHONPATH"] = whateveryouwanthere # add here the pythonpath that you want
cmd = ["mycmd.py", "myarg1", "myarg2"] # replace with your command
subprocess.call(cmd, env=new_env) #
# or alternatively if you also want to change the current directory
# subprocess.call(cmd, env=new_env, cwd=path_of_your_choice) #
你有一个 XY problem,虽然是可以理解的,因为开发 Python 项目的 "proper" 方法并不明显,而且没有很多好的指南入门(对此也有不同的看法,尤其是在细节上,尽管我认为我将在这里描述的内容很普遍)。
首先,您可以在项目的根目录下创建一个 setup.py
。现在这个文件可以只是一个存根;最终对它的需求应该完全消失,但一些工具仍然需要它:
$ cat setup.py
#!/usr/bin/env python
from setuptools import setup
setup()
然后创建一个setup.cfg
。对于大多数 Python 项目来说,这应该足够了——您只需要在 setup.py
中为特殊情况添加额外的代码。这是更复杂的 setup.cfg
的 template,但对于您的项目,您至少需要:
$ cat setup.cfg
[metadata]
name = project
version = 0.1.0
[options]
package_dir =
=thrift_packages/gen-py
packages = find:
现在创建并激活 virtual environment for your project(进入虚拟环境 in-depth 将超出此答案的范围,但我很乐意回答 follow-up 问题)。
$ mkdir -p ~/.virtualenvs
$ python3 -m venv ~/.virtualenvs/thrift
$ source ~/.virtualenvs/thrift/bin/activate
现在你应该有一个看起来像 (thrift) $
的提示,表明你在一个隔离的 virtualenv 中。在这里您可以为您的包安装任何依赖项,以及包本身,而不会干扰您的主要 Python 安装。
现在以 "editable" 模式安装您的包,这意味着当您 运行 Python(包括您的 top-level 脚本):
$ pip install -e .
如果您随后启动 Python 并导入您的包,您可以看到,例如:
$ python -c 'import thriftA'; print(thriftA)
<module 'thriftA' from '/path/to/your/source/code/project/thrift_packages/gen-py/thriftA/__init__.py'>
如果这看起来太麻烦,请相信我,事实并非如此。一旦你掌握了它(并且有几个项目模板,例如用 cookie-cutter 制作来摆脱它的想法)你会发现它使路径 less麻烦)。这就是我开始任何 non-trivial 项目(不仅仅是一个文件)的方式;如果您正确设置所有内容,您将永远不必担心手动使用 sys.path
或 $PYTHONPATH
。
在 this guide 中,虽然第一部分有点 application-specific,但如果忽略这段代码的具体用途,实际上很多内容都非常通用,尤其是标题为 [=61] 的部分=],其中更详细地重复了一些建议。
顺便说一句,如果您已经在使用 conda
,则不需要创建 virtualenv,因为 conda 环境只是花哨的 virtualenvs。
以 "right" 方式执行此操作的一个优点是,当需要 安装 您的软件包时,无论是您自己还是用户,如果您 setup.cfg
和 setup.py
设置正确,那么所有用户要做的就是 运行 pip install .
(没有 -e
),它应该以相同的方式工作。
我有一个包含多个脚本(scriptA、scriptB、scriptC)的 python 项目,这些脚本必须能够找到位于项目子路径中的不是 python 包或模块的包。组织是这样的:
|_project
|_scriptA.py
|_scriptB.py
|_scriptC.py
|_thrift_packages
|_gen-py
|_thriftA
|__init__.py
|_thriftA.py
在每个脚本的基础上,我将此目录的绝对路径添加到 sys.path
每次在项目中执行脚本时,我是否可以更改 PYTHONPATH 或 sys.path,这样我就不必将此目录的路径附加到 sys.path每个脚本的基础?
你应该在每个包中添加__init__.py
,然后正确调用你所有的脚本。
|_project
|_scriptA.py
|_scriptB.py
|_scriptC.py
|__init__.py <====== Here
|_thrift_packages
|__init__.py <====== Here
|_gen-py
|_thriftA
|__init__.py
|_thriftA.py
假设 project
在你的 pythonpath 中,你可以这样做:
from project.thrift_packages.thriftA import thriftA
是的,你可以。
但是我认为其他答案更适合您当前的问题。 这里我只是解释一下,如何调用另一个环境,另一个当前工作目录的子进程。 这在其他情况下可以派上用场。
您可以将当前环境作为字典获取 (os.environ),将其复制到另一个字典,对其进行修改并将其传递给 supbprocess 调用。 (子流程函数有一个 env 参数)
import os
import subprocess
new_env = dict(os.environ)
new_env["PYTHONPATH"] = whateveryouwanthere # add here the pythonpath that you want
cmd = ["mycmd.py", "myarg1", "myarg2"] # replace with your command
subprocess.call(cmd, env=new_env) #
# or alternatively if you also want to change the current directory
# subprocess.call(cmd, env=new_env, cwd=path_of_your_choice) #
你有一个 XY problem,虽然是可以理解的,因为开发 Python 项目的 "proper" 方法并不明显,而且没有很多好的指南入门(对此也有不同的看法,尤其是在细节上,尽管我认为我将在这里描述的内容很普遍)。
首先,您可以在项目的根目录下创建一个 setup.py
。现在这个文件可以只是一个存根;最终对它的需求应该完全消失,但一些工具仍然需要它:
$ cat setup.py
#!/usr/bin/env python
from setuptools import setup
setup()
然后创建一个setup.cfg
。对于大多数 Python 项目来说,这应该足够了——您只需要在 setup.py
中为特殊情况添加额外的代码。这是更复杂的 setup.cfg
的 template,但对于您的项目,您至少需要:
$ cat setup.cfg
[metadata]
name = project
version = 0.1.0
[options]
package_dir =
=thrift_packages/gen-py
packages = find:
现在创建并激活 virtual environment for your project(进入虚拟环境 in-depth 将超出此答案的范围,但我很乐意回答 follow-up 问题)。
$ mkdir -p ~/.virtualenvs
$ python3 -m venv ~/.virtualenvs/thrift
$ source ~/.virtualenvs/thrift/bin/activate
现在你应该有一个看起来像 (thrift) $
的提示,表明你在一个隔离的 virtualenv 中。在这里您可以为您的包安装任何依赖项,以及包本身,而不会干扰您的主要 Python 安装。
现在以 "editable" 模式安装您的包,这意味着当您 运行 Python(包括您的 top-level 脚本):
$ pip install -e .
如果您随后启动 Python 并导入您的包,您可以看到,例如:
$ python -c 'import thriftA'; print(thriftA)
<module 'thriftA' from '/path/to/your/source/code/project/thrift_packages/gen-py/thriftA/__init__.py'>
如果这看起来太麻烦,请相信我,事实并非如此。一旦你掌握了它(并且有几个项目模板,例如用 cookie-cutter 制作来摆脱它的想法)你会发现它使路径 less麻烦)。这就是我开始任何 non-trivial 项目(不仅仅是一个文件)的方式;如果您正确设置所有内容,您将永远不必担心手动使用 sys.path
或 $PYTHONPATH
。
在 this guide 中,虽然第一部分有点 application-specific,但如果忽略这段代码的具体用途,实际上很多内容都非常通用,尤其是标题为 [=61] 的部分=],其中更详细地重复了一些建议。
顺便说一句,如果您已经在使用 conda
,则不需要创建 virtualenv,因为 conda 环境只是花哨的 virtualenvs。
以 "right" 方式执行此操作的一个优点是,当需要 安装 您的软件包时,无论是您自己还是用户,如果您 setup.cfg
和 setup.py
设置正确,那么所有用户要做的就是 运行 pip install .
(没有 -e
),它应该以相同的方式工作。