我有一个充满脚本的目录(比方说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平台,但它可以保持干净。
答案 0 :(得分:96)
这就是我使用的:
import os, sys
sys.path.append(os.path.join(os.path.dirname(__file__), "lib"))
答案 1 :(得分:22)
我正在使用:
import sys,os
sys.path.append(os.getcwd())
答案 2 :(得分:20)
如果您不想编辑每个文件
PYTHONPATH
设置为lib
或者如果您愿意为每个文件添加一行,请在顶部添加一个import语句。
import import_my_lib
将import_my_lib.py
保留在bin中,import_my_lib
可以正确地将python路径设置为您想要的lib
答案 3 :(得分:11)
创建一个包装器模块project/bin/lib
,其中包含:
import sys, os
sys.path.insert(0, os.path.join(
os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib'))
import mylib
del sys.path[0], sys, os
然后,您可以使用以下命令替换脚本顶部的所有内容:
#!/usr/bin/python
from lib import mylib
答案 4 :(得分:5)
如果您不想以任何方式更改脚本内容,请将当前工作目录.
添加到$ PYTHONPATH(请参阅下面的示例)
PYTHONPATH=.:$PYTHONPATH alembic revision --autogenerate -m "First revision"
并称之为一天!
答案 5 :(得分:4)
使用python 3.4+
禁止使用cx_freeze或在IDLE中使用。
import sys
from pathlib import Path
sys.path.append(Path(__file__).parent / "lib")
答案 6 :(得分:3)
我多次这样做:
import os
import sys
current_path = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(current_path, "lib"))
答案 7 :(得分:2)
每个答案都有问题可以概括为"只需将这个神奇的咒语添加到脚本的开头即可。看看只用一两行代码就可以做些什么。" 他们无法在所有可能的情况下工作!
例如,一个这样的神奇咒语使用文件。不幸的是,如果使用cx_Freeze打包脚本或使用IDLE,则会导致异常。
另一个这样神奇的咒语使用os.getcwd()。这仅在从命令提示符运行脚本时才有效,并且包含脚本的目录是当前工作目录(即在运行脚本之前使用cd命令更改为目录)。哎呀!我希望我不必解释为什么如果你的Python脚本在某个地方的PATH中并且你只需输入脚本文件的名称来运行它就不会起作用。
幸运的是,有一个神奇的咒语适用于我测试过的所有情况。不幸的是,神奇的咒语不仅仅是一两行代码。
import inspect
import os
import sys
# Add script directory to sys.path.
# This is complicated due to the fact that __file__ is not always defined.
def GetScriptDirectory():
if hasattr(GetScriptDirectory, "dir"):
return GetScriptDirectory.dir
module_path = ""
try:
# The easy way. Just use __file__.
# Unfortunately, __file__ is not available when cx_freeze is used or in IDLE.
module_path = __file__
except NameError:
if len(sys.argv) > 0 and len(sys.argv[0]) > 0 and os.path.isabs(sys.argv[0]):
module_path = sys.argv[0]
else:
module_path = os.path.abspath(inspect.getfile(GetScriptDirectory))
if not os.path.exists(module_path):
# If cx_freeze is used the value of the module_path variable at this point is in the following format.
# {PathToExeFile}\{NameOfPythonSourceFile}. This makes it necessary to strip off the file name to get the correct
# path.
module_path = os.path.dirname(module_path)
GetScriptDirectory.dir = os.path.dirname(module_path)
return GetScriptDirectory.dir
sys.path.append(os.path.join(GetScriptDirectory(), "lib"))
print(GetScriptDirectory())
print(sys.path)
如您所见,这不是一件容易的事!
答案 8 :(得分:0)
您可以从相关的根目录使用python -m
运行脚本。并将“模块路径”作为参数传递。
示例:$ python -m module.sub_module.main # Notice there is no '.py' at the end.
另一个例子:
$ tree # Given this file structure
.
├── bar
│ ├── __init__.py
│ └── mod.py
└── foo
├── __init__.py
└── main.py
$ cat foo/main.py
from bar.mod import print1
print1()
$ cat bar/mod.py
def print1():
print('In bar/mod.py')
$ python foo/main.py # This gives an error
Traceback (most recent call last):
File "foo/main.py", line 1, in <module>
from bar.mod import print1
ImportError: No module named bar.mod
$ python -m foo.main # But this succeeds
In bar/mod.py
答案 9 :(得分:0)
这个最适合我。 使用:
os.path.abspath('')
在Mac上,它应显示以下内容:
'/Users/<your username>/<path_to_where_you_at>'
要获取当前wd的绝对路径,最好使用此路径,因为现在您可以根据需要向上走,就像这样:
os.path.abspath('../')
现在:
'/Users/<your username>/'
因此,如果您想从此处utils
导入'/Users/<your username>/'
您剩下要做的就是:
import sys
sys.path.append(os.path.abspath('../'))
答案 10 :(得分:0)
在您的示例中,我看到了一个爆炸。如果您以./bin/foo.py
而不是python ./bin/foo.py
的身份运行bin脚本,则可以选择使用shebang更改$PYTHONPATH
变量。
尽管您不能直接在shebang中更改环境变量,所以您将需要一个小的帮助程序脚本。将此python.sh
放入您的bin
文件夹:
#!/usr/bin/env bash
export PYTHONPATH=$PWD/lib
exec "/usr/bin/python" "$@"
然后将您的./bin/foo.py
的shebang更改为#!bin/python.sh
答案 11 :(得分:0)
当我们尝试通过终端路径运行python文件时。
import sys
#For file name
file_name=sys.argv[0]
#For first argument
dir= sys.argv[1]
print("File Name: {}, argument dir: {}".format(file_name, dir)
保存文件(test.py)。
运行系统。
打开终端,然后转到保存文件的那个目录。 然后写
python test.py "/home/saiful/Desktop/bird.jpg"
点击进入
输出:
File Name: test, Argument dir: /home/saiful/Desktop/bird.jpg
答案 12 :(得分:0)
我使用:
from site import addsitedir
然后,可以使用任何相对目录!
addsitedir('..\lib')
;这两个点表示先将一个目录上移(上移)。
请记住,这完全取决于您当前的工作目录。 如果C:\ Joe \ Jen \ Becky,则 addsitedir('.. \ lib')导入到您的路径C:\ Joe \ Jen \ lib
C:\
|__Joe
|_ Jen
| |_ Becky
|_ lib