大学项目Python多进程依赖安装脚本报错TypeError: run_cmd() takes 1 positional argument but N were given的解决方案求助
问题原因分析
你遇到的错误核心问题是多进程传参格式不正确:mp.Process的args参数要求传入一个元组,但你直接传了一个空格分隔的字符串。Python会把字符串当作可迭代对象,将每个字符拆成单独的参数传递给run_cmd函数,而你的run_cmd只接受1个参数,所以才会报“takes 1 positional argument but N were given”的错误。
另外还有几个小问题需要一并修正:
tkinter是Python标准库组件,不需要通过pip安装,应该从安装列表中移除- 使用
os.system执行命令不够灵活,换成subprocess.run能更好地控制命令执行和捕获输出 - 所有多进程相关的启动代码都应该放在
if __name__ == '__main__':代码块内,避免Windows环境下出现重复启动进程的问题
修复后的完整代码
#------------------------------------------------------------------------------- # Name: DBC Installations # Purpose: Install necessary components needed for DBC # # Author: MS Productions # Created: 19/09/2022 # Copyright: (c) MS Productions 2022 #------------------------------------------------------------------------------- import time import sys import subprocess import os import multiprocessing as mp def run_cmd(package_list): # 将传入的包列表字符串拆分成单个包,逐个安装 for package in package_list.split(): cmd = [sys.executable, "-m", "pip", "install", package] print(f"[INSTALLING] {package}") try: # 使用subprocess.run执行命令,捕获输出并检查返回码 result = subprocess.run(cmd, check=True, capture_output=True, text=True) print(f"[SUCCESS] {package} installed") print(result.stdout) except subprocess.CalledProcessError as e: print(f"[FAILED] {package} installation failed") print(e.stderr) if __name__ == '__main__': print("[INFO] Running script -") print("[INFO] Installing modules :") start = time.perf_counter() # 注意args要传元组,末尾加逗号确保是元组类型 p1 = mp.Process(target=run_cmd, args=("pynput pyautogui datetime selenium openpyxl",)) p2 = mp.Process(target=run_cmd, args=("numpy pystray struct Pillow",)) p1.start() p2.start() p1.join() p2.join() finish = time.perf_counter() print(f'Finished in {round(finish-start, 2)} second(s)')
关键修改点说明
多进程传参格式修正:
把args="xxx"改成args=("xxx",),末尾的逗号是必须的,用来确保这是一个单元素元组,而不是普通的字符串。移除tkinter并优化安装逻辑:
去掉了不需要pip安装的tkinter,同时在run_cmd里把包列表字符串拆分后逐个安装,这样能更清晰地看到每个包的安装状态。使用sys.executable调用pip:
用sys.executable获取当前Python解释器的路径,再通过-m pip执行安装,避免因为环境变量问题调用到错误的Python版本的pip。替换os.system为subprocess.run:
可以捕获每个包安装的成功/失败信息,方便调试,同时check=True会在命令执行失败时抛出异常,便于处理错误。调整代码结构:
把所有启动进程的代码都放到if __name__ == '__main__':里面,这是Windows系统下使用多进程的必要操作,防止子进程重复执行整个脚本。
内容的提问来源于stack exchange,提问作者MT_276
相关产品推荐
相关产品推荐

