wkdxz 发表于 2023-9-3 16:33

【重装救急】批量安装python源文件中import了的库

本帖最后由 wkdxz 于 2023-9-6 09:20 编辑

备份当前已安装的库,本来应该执行以下步骤,先运行pip freeze > requirements.txt
然后运行pip install -r requirements.txt


然而,我今天手欠将python3.8.5升级到3.10.4,发现原先的库好多都不兼容,用不了。之前的库也忘了备份到requirements.txt。
想换回原先的版本,安装时一直提示:0x80070001错误。于是我慌了,一堆脚本需要调用的,如果一下子都用不了,我的工作量估计要增加好几倍。
于是有了下面的代码:

功能:

[*]查找指定目录内已有的python源文件
[*]找出文件里import了哪些库
[*]然后使用代码判断这些库是否安装
[*]未安装就使用pip install安装库

虽然代码简单,但帮了我大忙,只花了10多分钟时间,我的python又满血复活了。{:1_927:}

import os
import ast
import subprocess


def dir_files(directory, extension):
    """遍历目录内指定后缀"""
    file_list = []
    for root, dirs, files in os.walk(directory):
      for file in files:
            if file.endswith(extension):
                if "tempCodeRunnerFile" not in file:# CodeRunner生成的临时文件忽略掉
                  file_list.append(os.path.join(root, file))
    return file_list


def py_file_list(python_file_folders):
    """查找指定目录内容的python文件"""
    pylist = []
    for directory_to_search in python_file_folders:
      for f in [".py", ".pyw"]:# python文件后缀
            tmp_files = dir_files(directory_to_search, f)
            pylist += tmp_files
    return pylist


def parse_imports(filename):
    """解析python源文件import了哪些库"""
    with open(filename, "r", encoding="utf-8") as f:
      tree = ast.parse(f.read())
    imports = set()
    for node in ast.iter_child_nodes(tree):
      if isinstance(node, ast.Import):
            for alias in node.names:
                imports.add(alias.name.split("."))
      elif isinstance(node, ast.ImportFrom):
            module_name = node.module.split(".") if node.module else ""
            for alias in node.names:
                imports.add(module_name + "." + alias.name.split("."))

    return list(imports)


def pip_install(libraries):
    """判断是否安装了库 没有就直接pip安装"""
    for library in libraries:
      library = library.split(".")
      try:
            __import__(library)
            # print(library, "已安装")
      except ImportError:
            print(f"{library} 没有安装,正在使用pip安装...")
            subprocess.call(["pip", "install", library])
            # print("未安装:", library)


if __name__ == "__main__":
    py_folders =

    py_lists = py_file_list(py_folders)
    # print(py_lists)

    all_imports = []
    # 输出列表中的文件路径
    for py_file in py_lists:
      imports = parse_imports(py_file)

      # print(py_file, imports)

      all_imports += for library in imports]

    if imports:
      imports = set(all_imports)
      pip_install(imports)

爱飞的猫 发表于 2023-9-3 17:33

如果代码重要,就应该提前记录到 requirements 里面

另外一般都会用 venv 在项目目录建立一个独立的 Python 环境,隔离 Python 依赖

吾乃齐天大圣 发表于 2023-9-3 17:59

遇事不要慌{:1_921:}

ccber 发表于 2023-9-3 19:58

我一直想整一个离线版的安装。

sai609 发表于 2023-9-3 20:36

一、安装andconda,内置多个第三方库
二、最新的版本,得卸载旧版,install安装最新的。。。。但是有时会新旧or与其他库共存而冲突

666888tzq 发表于 2023-9-3 21:08

我的Python自打安装了就没打开过几次。:lol

moruye 发表于 2023-9-3 23:26

lcg2014 发表于 2023-9-4 09:30

学习经验,保持进步

fatsheepfy58 发表于 2023-9-4 11:05

出现问题,解决问题,赞

三滑稽甲苯 发表于 2023-9-5 21:57

如果其中有的库只支持 Python 3.8.5,阁下又当如何应对 {:301_998:}
页: [1] 2
查看完整版本: 【重装救急】批量安装python源文件中import了的库