Python:添加到相对于当前运行脚本的 sys.path 的最佳方法
我有一个充满脚本的目录(比如说 project/bin
)。我还有一个位于 project/lib
中的库,并希望脚本自动加载它。这是我通常在每个脚本的顶部使用的内容:
#!/usr/bin/python
from os.path import dirname, realpath, sep, pardir
import sys
sys.path.append(dirname(realpath(__file__)) + sep + pardir + sep + "lib")
# ... now the real code
import mylib
这有点麻烦、丑陋,并且必须粘贴在每个文件的开头。有更好的方法吗?
我真正希望的是像这样顺利的东西:
#!/usr/bin/python
import sys.path
from os.path import pardir, sep
sys.path.append_relative(pardir + sep + "lib")
import mylib
或者更好的是,当我的编辑器(或具有提交访问权限的其他人)决定重新排序导入作为其清理过程的一部分时,不会中断的东西:
#!/usr/bin/python --relpath_append ../lib
import mylib
这不会直接移植到非 posix 平台,但它会让事情保持干净。
I have a directory full of scripts (let's say project/bin
). I also have a library located in project/lib
and want the scripts to automatically load it. This is what I normally use at the top of each script:
#!/usr/bin/python
from os.path import dirname, realpath, sep, pardir
import sys
sys.path.append(dirname(realpath(__file__)) + sep + pardir + sep + "lib")
# ... now the real code
import mylib
This is kind of cumbersome, ugly, and has to be pasted at the beginning of every file. Is there a better way to do this?
Really what I'm hoping for is something as smooth as this:
#!/usr/bin/python
import sys.path
from os.path import pardir, sep
sys.path.append_relative(pardir + sep + "lib")
import mylib
Or even better, something that wouldn't break when my editor (or someone else who has commit access) decides to reorder the imports as part of its clean-up process:
#!/usr/bin/python --relpath_append ../lib
import mylib
That wouldn't port directly to non-posix platforms, but it would keep things clean.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
这就是我使用的:
This is what I use:
我正在使用:
I'm using:
如果您不想编辑每个文件,
或
PYTHONPATH
设置为您的lib
,或者如果您愿意向每个文件添加一行,请在顶部添加导入语句,例如
保留
import_my_lib.py
bin 中的 code> 和 import_my_lib 可以正确地将 python 路径设置为你想要的任何lib
If you don't want to edit each file
or
PYTHONPATH
to yourlib
or if you are willing to add a single line to each file, add a import statement at top e.g.
keep
import_my_lib.py
in bin andimport_my_lib
can correctly set the python path to whateverlib
you want创建一个包装器模块
project/bin/lib
,其中包含以下内容:然后您可以将脚本顶部的所有内容替换为:
Create a wrapper module
project/bin/lib
, which contains this:Then you can replace all the cruft at the top of your scripts with:
使用Python 3.4+
Using python 3.4+
您可以使用
python -m
从相关根目录运行脚本。并将“模块路径”作为参数传递。示例:
$ python -m module.sub_module.main # 注意末尾没有“.py”。
另一个示例:
You can run the script with
python -m
from the relevant root dir. And pass the "modules path" as argument.Example:
$ python -m module.sub_module.main # Notice there is no '.py' at the end.
Another example:
如果您不想以任何方式更改脚本内容,请将当前工作目录
.
添加到 $PYTHONPATH (参见下面的示例)并收工!
If you don't want to change the script content in any ways, prepend the current working directory
.
to $PYTHONPATH (see example below)And call it a day!
我多次都是这样做的:
This is how I do it many times:
提供的每个答案都存在一个问题,可以概括为“只需将这个神奇的咒语添加到脚本的开头即可。看看只用一两行代码可以做什么。” 它们不会在所有可能的情况下都起作用!
例如,一个这样的神奇咒语使用
__file__
。不幸的是,如果您使用 cx_Freeze 打包脚本或使用 IDLE,这将导致异常。另一个这样神奇的咒语使用 os.getcwd()。仅当您从命令提示符运行脚本并且包含脚本的目录是当前工作目录(即您在运行脚本之前使用 cd 命令切换到该目录)时,这才有效。哎呀诸神啊!我希望我不必解释为什么如果你的 Python 脚本位于 PATH 中的某个位置并且你只需键入脚本文件的名称来运行它,这将不起作用。
幸运的是,有一个神奇的咒语适用于我测试过的所有情况。不幸的是,神奇的咒语不仅仅是一两行代码。
正如您所看到的,这不是一件容易的事!
There is a problem with every answer provided that can be summarized as "just add this magical incantation to the beginning of your script. See what you can do with just a line or two of code." They will not work in every possible situation!
For example, one such magical incantation uses
__file__
. Unfortunately, if you package your script using cx_Freeze or you are using IDLE, this will result in an exception.Another such magical incantation uses os.getcwd(). This will only work if you are running your script from the command prompt and the directory containing your script is the current working directory (that is you used the cd command to change into the directory prior to running the script). Eh gods! I hope I do not have to explain why this will not work if your Python script is in the PATH somewhere and you ran it by simply typing the name of your script file.
Fortunately, there is a magical incantation that will work in all the cases I have tested. Unfortunately, the magical incantation is more than just a line or two of code.
As you can see, this is no easy task!
我在你的例子中看到了一个shebang。如果您以
./bin/foo.py
运行 bin 脚本,而不是python ./bin/foo.py
,则可以选择使用 shebang更改 $PYTHONPATH 变量。不过,您无法直接在 shebangs 中更改环境变量,因此您需要一个小的帮助程序脚本。将这个
python.sh
放入您的bin
文件夹中:然后将您的
./bin/foo.py
的shebang更改为#!bin/python.sh
I see a shebang in your example. If you're running your bin scripts as
./bin/foo.py
, rather thanpython ./bin/foo.py
, there's an option of using the shebang to change$PYTHONPATH
variable.You can't change environment variables directly in shebangs though, so you'll need a small helper script. Put this
python.sh
into yourbin
folder:And then change the shebang of your
./bin/foo.py
to be#!bin/python.sh
我使用:
然后,可以使用任何相对目录!
addsitedir('..\lib')
;两个点表示首先移动(上移)一个目录。请记住,这完全取决于您当前的工作目录是从哪个目录开始的。
如果 C:\Joe\Jen\Becky,那么
addsitedir('..\lib') 导入到您的路径 C:\Joe\Jen\lib
I use:
Then, can use any relative directory !
addsitedir('..\lib')
; the two dots implies move (up) one directory first.Remember that it all depends on what your current working directory your starting from.
If C:\Joe\Jen\Becky, then
addsitedir('..\lib') imports to your path C:\Joe\Jen\lib
当我们尝试从终端运行带有路径的 python 文件时。
保存文件(test.py)。
运行系统。
打开终端并转到保存文件的目录。
然后写
Hit Enter
输出:
When we try to run python file with path from terminal.
Save the file (test.py).
Runing system.
Open terminal and go the that dir where is save file.
then write
Hit enter
Output:
在模块之前添加这两行:
我的文件结构如下:
和我的测试代码:
这样我就可以在终端中优雅地运行工具模块中的代码,我使用:
Add these two lines before your module:
My file structure as below:
and my test code:
So that I can run my code in tool module elegantly in terminal, I use: