我想在我的Python脚本文件夹中包含一个第三方库,以将其全部分发(我不知道发行许可证,可以很好地分发该库)。这是为了避免将库安装在另一台机器上。
说我有一个脚本(my_script.py
),它将调用此外部库。我试图将此库从Python目录的site-packages子目录复制到我有文件的目录中,但这似乎还不够(我认为原因是该库的__init__.py
中可能需要使用文件夹在PYTHONPATH
中)。
为了使所有内容正常工作,在my_script.py
中插入几行代码以将其文件夹临时追加到sys.path
中是否合理?
例如,如果我有一个类似于以下的结构:
Main_folder
my_script.py
/external_lib_folder
__init__.py
external_lib.py
并且
external_lib_folder
是我从网站程序包中复制并插入到Main_folder
中的外部库,如果我将这些行(例如)写在my_script.py
中会好吗?import os,sys
main_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(main_dir)
编辑
我最终选择了
sys.path.append
解决方案。我将这些行添加到了my_script.py
中:import os, sys
# temporarily appends the folder containing this file into sys.path
main_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),'functions')
sys.path.append(main_dir)
无论如何,由于他花了很多时间在帮助我上(当然,因为他的解决方案也行得通),所以我选择将其作为问题的编辑内容并接受Torxed的答案。
最佳答案
Python3
import importlib.machinery, imp
namespace = 'external_lib'
loader = importlib.machinery.SourceFileLoader(namespace, '/home/user/external_lib_folder/external_lib.py')
external_lib = loader.load_module(namespace)
# How to use it:
external_lib.function(data_or_something)
这将是在Python 3中加载自定义路径的理想方法。
并不完全确定这是您想要的,但是它的相关性足以发布添加到
sys.path
的替代方法。Python2
在python 2中,您可以做(如果我没记错的话,有一段时间了,因为我使用的是旧版本的Python):
external_lib = __import__('external_lib_folder')
但是,这确实需要您在悲伤的脚本中保留
__init__.py
和正确的函数声明,否则它将失败。**同样重要的是,您要导入的文件夹的名称与sad文件夹中
__init__.py
脚本试图从其导入子库的名称相同,例如geopy
将为:./myscript.py
./geopy/
./geopy/__init__.py
./geopy/compat.py
...
myscript.py
的代码如下所示:handle = __import__('geopy')
print(handle)
这将产生以下输出:
[user@machine project]$ python2 myscript.py
<module 'geopy' from '/home/user/project/geopy/__init__.pyc'>
[user@machine project]$ tree -L 2
.
├── geopy
│ ├── compat.py
│ ├── compat.pyc
│ ├── distance.py
│ ├── distance.pyc
│ ├── exc.py
│ ├── exc.pyc
│ ├── format.py
│ ├── format.pyc
│ ├── geocoders
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── location.py
│ ├── location.pyc
│ ├── point.py
│ ├── point.pyc
│ ├── units.py
│ ├── units.pyc
│ ├── util.py
│ ├── util.pyc
│ └── version.pyc
└── myscript.py
2 directories, 20 files
因为在
__init__.py
的geopy
中,它定义了导入,例如from geopy.point import Point
,它需要存在 namespace 或geopy
文件夹。在那里,您无法将文件夹重命名为
functions
并在其中放置名为geopy
的文件夹,因为那样将无法工作,也无法将geopy
的内容放置在名为functions
的文件夹中,因为这不是geopy
所要查找的。将路径添加到
sys.path
(Py2 + 3)如注释中所述,您还可以在导入之前将该文件夹添加到
sys.path
变量中。import sys
sys.path.insert(0, './functions')
import geopy
print(geopy)
>>> <module 'geopy' from './functions/geopy/__init__.pyc'>
为什么这是个坏主意:它可以工作,并且被许多人使用。可能出现的问题是,如果您不小心从中导入内容,则可能会替换系统功能,或者其他模块可能会从其他文件夹加载。大多数情况下都可以使用
.insert(0, ...)
,并确保您确实有冒着用“不透明”路径名替换系统内置组件的风险。关于Python:在个人Python包中包含第三方库,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35849429/