使用 Python 列出依赖项
- 2025-03-20 08:46:00
- admin 原创
- 36
问题描述:
列出在其他地方(比如说,在不同的操作系统上)部署工作项目所需的所有依赖项的最有效方法是什么?
Python 2.7,Windows 开发环境,不是为每个项目使用一个虚拟环境,而是使用一个全局开发环境,根据需要安装库,愉快地从一个项目跳转到另一个项目。
我跟踪了大多数(不确定是全部)我必须为特定项目安装的库。我没有跟踪任何自动安装的子依赖项。执行操作pip freeze
会列出这两个库,以及曾经安装的所有其他库。
有没有办法列出部署项目所需安装的内容(不多不少)?
编辑鉴于以下答案,需要澄清一些问题。我的项目由一堆模块(我编写的)组成,每个模块都有一堆import
s。我是否应该将所有模块中的所有导入复制粘贴到一个文件中,排序以消除重复项,然后从标准库中删除所有内容(我怎么知道它们是什么)?或者有更好的方法吗?这就是问题所在。
解决方案 1:
pipreqs
解决了这个问题。它生成项目级requirement.txt文件。
安装 pipreqs:pip install pipreqs
生成项目级requirement.txt文件:
pipreqs /path/to/your/project/
需求文件将保存在 /path/to/your/project/requirements.txt
如果你想了解更多的优势pipreqs
,请从这里pip freeze
阅读
解决方案 2:
扫描您的import
语句。您可能只导入了明确想要导入的内容,而不是依赖项。
创建一个类似的列表pip freeze
,然后创建并激活一个虚拟环境。
执行pip install -r your_list
,并尝试在该虚拟环境中运行您的代码。注意任何ImportError
异常,将它们与包匹配,然后添加到您的列表中。重复操作,直到您的代码运行无问题。
pip install
现在您有一个可以在部署站点上提供的列表。
这是非常手动的,但不需要外部工具,并迫使您确保您的代码可以运行。(运行测试套件作为检查很好但还不够。)
解决方案 3:
在你的终端类型上:
pip install pipdeptree
cd <your project root>
pipdeptree
解决方案 4:
您可以简单地使用pipreqs,使用以下命令安装它:
pip install pipreqs
然后,在文件目录中输入pipreqs .
:。将为您创建一个名为 requirements 的文本文件,如下所示:
numpy==1.21.1
pytest==6.2.4
matplotlib==3.4.2
PySide2==5.15.2
解决方案 5:
您可以使用我编写的findpydeps模块:
通过 pip 安装:
pip install findpydeps
如果您有一个主文件:(
findpydeps -l -i path/to/main.py
将-l
遵循文件中的导入)或者你的代码位于一个文件夹中:
findpydeps -i path/to/folder
最重要的是,输出是 pip 友好的:
执行
findpydeps -i . > requirements.txt
(假设.
是你的项目目录)然后
pip install -r requirements.txt
当然,您可以搜索多个目录和文件来查找要求,例如:findpydeps -i path/to/file1.py path/to/folder path/to/file2.py
等等。
默认情况下,它将删除 Python 标准库中的包以及本地包。有关更多信息,请参阅-r
/参数。--removal-policy
如果您不想在if、try/except或with块中完成导入,只需添加。带有 的函数--no-blocks
也是如此。--no-functions
无论如何,您已经明白了:有很多选项(其中大多数未在此处讨论)。请参阅findpydeps -h
输出以获取更多帮助!
解决方案 6:
我发现这里的答案对我来说不太好,因为我只想要从我们的存储库内部导入(例如,import requests
我不需要,但from my.module.x import y
我确实需要)。
不过,我注意到它PyInstaller
在这方面具有非常好的功能。我做了一些挖掘,设法找到了它们的依赖图代码,然后创建了一个函数,经过一些反复试验,就可以完成我想要的操作。我在这里做了一个要点,因为我将来可能会再次需要它,但这里是代码:
import os
from PyInstaller.depend.analysis import initialize_modgraph
def get_import_dependencies(*scripts):
"""Get a list of all imports required.
Args: script filenames.
Returns: list of imports
"""
script_nodes = []
scripts = set(map(os.path.abspath, scripts))
# Process the scripts and build the map of imports
graph = initialize_modgraph()
for script in scripts:
graph.run_script(script)
for node in graph.nodes():
if node.filename in scripts:
script_nodes.append(node)
# Search the imports to find what is in use
dependency_nodes = set()
def search_dependencies(node):
for reference in graph.getReferences(node):
if reference not in dependency_nodes:
dependency_nodes.add(reference)
search_dependencies(reference)
for script_node in script_nodes:
search_dependencies(script_node)
return list(sorted(dependency_nodes))
if __name__ == '__main__':
# Show the PyInstaller imports used in this file
for node in get_import_dependencies(__file__):
if node.identifier.split('.')[0] == 'PyInstaller':
print(node)
所有节点类型均在 中定义PyInstaller.lib.modulegraph.modulegraph
,例如SourceModule
、和MissingModule
。这些在执行检查时非常有用。Package
`BuiltinModule`
其中每个都有一个identifier
( path.to.my.module
),并且根据节点类型,它可能有一个filename
( C:/path/to/my/module/__init__.py
) 和packagepath
( ['C:/path/to/my/module']
)。
我实际上无法发布任何额外的代码,因为它特定于我们使用的设置pyarmor
,PyInstaller
但我可以高兴地说它到目前为止运行良好。
解决方案 7:
如果您使用 Anaconda 虚拟环境,则可以在环境中运行以下命令来创建项目中使用的所有依赖项的 txt 文件。
conda list -e > requirements.txt
解决方案 8:
实现此目的的方法是分析导入。要实现自动化,请查看Snakefood。然后,您可以创建一个requirements.txt
文件并开始使用virtualenv
。
下面将列出依赖项,不包括标准库中的模块:
sfood -fuq package.py | sfood-filter-stdlib | sfood-target-files
相关问题:
获取 Django 项目使用的 Python 包列表
列出 python 包依赖项但不加载它们?
解决方案 9:
我只需要运行如下命令:
import importlib
import os
import pathlib
import re
import sys, chardet
from sty import fg
sys.setrecursionlimit(100000000)
dependenciesPaths = list()
dependenciesNames = list()
paths = sys.path
red = fg(255, 0, 0)
green = fg(0, 200, 0)
end = fg.rs
def main(path):
try:
print("Finding imports in '" + path + "':")
file = open(path)
contents = file.read()
wordArray = re.split(" |
", contents)
currentList = list()
nextPaths = list()
skipWord = -1
for wordNumb in range(len(wordArray)):
word = wordArray[wordNumb]
if wordNumb == skipWord:
continue
elif word == "from":
currentList.append(wordArray[wordNumb + 1])
skipWord = wordNumb + 2
elif word == "import":
currentList.append(wordArray[wordNumb + 1])
currentList = set(currentList)
for i in currentList:
print(i)
print("Found imports in '" + path + "'")
print("Finding paths for imports in '" + path + "':")
currentList2 = currentList.copy()
currentList = list()
for i in currentList2:
if i in dependenciesNames:
print(i, "already found")
else:
dependenciesNames.append(i)
try:
fileInfo = importlib.machinery.PathFinder().find_spec(i)
print(fileInfo.origin)
dependenciesPaths.append(fileInfo.origin)
currentList.append(fileInfo.origin)
except AttributeError as e:
print(e)
print(i)
print(importlib.machinery.PathFinder().find_spec(i))
# print(red, "Odd noneType import called ", i, " in path ", path, end, sep='')
print("Found paths for imports in '" + path + "'")
for fileInfo in currentList:
main(fileInfo)
except Exception as e:
print(e)
if __name__ == "__main__":
# args
args = sys.argv
print(args)
if len(args) == 2:
p = args[1]
elif len(args) == 3:
p = args[1]
open(args[2], "a").close()
sys.stdout = open(args[2], "w")
else:
print('Usage')
print('PyDependencies <InputFile>')
print('PyDependencies <InputFile> <OutputFile')
sys.exit(2)
if not os.path.exists(p):
print(red, "Path '" + p + "' is not a real path", end, sep='')
elif os.path.isdir(p):
print(red, "Path '" + p + "' is a directory, not a file", end, sep='')
elif "".join(pathlib.Path(p).suffixes) != ".py":
print(red, "Path '" + p + "' is not a python file", end, sep='')
else:
print(green, "Path '" + p + "' is a valid python file", end, sep='')
main(p)
deps = set(dependenciesNames)
print(deps)
sys.exit()
解决方案 10:
这个答案是为了帮助某人列出 Python 脚本本身的所有依赖项及其版本。这将列出用户虚拟环境中的所有依赖项。
from pip._internal.operations import freeze
x = freeze.freeze()
for dependency in x:
print(dependency)
为此,您需要将其pip
作为依赖项进行安装。使用以下命令安装 pip 依赖项。
pip install pip
打印输出如下所示。
certifi==2020.12.5
chardet==4.0.0
idna==2.10
numpy==1.20.3
oauthlib==3.1.0
pandas==1.2.4
pip==21.1.2
python-dateutil==2.8.1
pytz==2021.1
requests==2.25.1
requests-oauthlib==1.3.0
setuptools==41.2.0
six==1.16.0
urllib3==1.26.4
扫码咨询,免费领取项目管理大礼包!