pycharm运行正常,但命令行执行提示module不存在的多种解决方式(全)

文章讲述了在测试模块中遇到的包不存在错误,分析了PyCharm和命令行环境下sys.path的不同,给出了设置正确包路径的五种方法,包括写死绝对路径、使用os获取、添加到环境变量等,强调路径问题通常是这类问题的根源。
摘要由CSDN通过智能技术生成

问题描述

在这里插入图片描述
在执行某个测试模块时出现提示,显示自定义模块data不存在,但是在PyCharm下运行正常。错误信息如下:

Traceback (most recent call last):
  File "/run/channelnterface-autocase/testcases/test_chanel_detail.py", line 2, in <module>
    from data.chanel_detail_makecase import *
ModuleNotFoundError: No module named 'data'

问题原因

大部分情况下,此类问题是由于包的路径没有设置正确所致。通过打印 PyCharm 和命令行下的 sys.path 路径信息对比,可以发现以下差异:
在当前目录下__init__添加

import sys
print("系统路径",sys.path)

分别用PyCharm与命令行执行

  • PyCharm
    包含了当前的目录以及这个代码的根目录(前提是需要将这个根目录设置为Sources Root)
    在这里插入图片描述
    结果:系统路径 [‘D:\uitest\channelnterface-autocase\testcases’, ‘D:\uitest’, ‘D:\uitest\channelnterface-autocase’…

  • 使用Pyhton命令行执行
    结果为系统路径 [‘D:\uitest\channelnterface-autocase\testcases’…

在PyCharm设置了Sources Root,向系统变量增加了当前目录的根目录,所以PyCharm运行时能找到自定义包的。但Pyhton命令行执行时少了添加根目录路径的步骤,导致找不到包了。

解决方法

向执行代码中添加根目录路径,一般添加在头部

方法一:写死绝对路径
import sys
sys.path.append('xxx/xxx/xxx/')
方法二:使用os获取

os.path.dirname获取目录,此处就是获取目录的父目录。如果目录层级更多,就需要多加一层 os.path.dirname

import os,sys
project_root =  os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(project_root)
方法三:os获取+/…/

如果层级更多,则需要多加"…/" ,看起来比方法二更加简洁点

import os,sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../')
方法四,直接加到环境变量path中

输入以下命令

export PYTHONPATH=$PYTHONPATH:/xxx/

export 命令输入只临时生效,重新连接会失效,或者直接修改环境配置~/.bashrc等配置加上这句可以实现永久解决问题,如果这个不能实现,考虑自己手动去执行添加

方法五,subprocess.run 使用env变量

有些人是在subprocess去执行脚本,这个时候用上述的方法就不太能永久解决问题。我们可以使用subprocess的env参数去做,代码如下

    def run_script(self, script_path, *args):
        # 运行 Python 脚本
        path_parts = script_path.split('/')
        export_commands = []
        for i in range(1, len(path_parts)):
            path_part = '/'.join(path_parts[:i])
            export_commands.append(f'{path_part}')
        env = os.environ.copy()
        env['PYTHONPATH'] = ':'.join(export_commands) + ':' + env.get('PYTHONPATH', '')
        # print(f"env{env}")
        script_dir = os.path.dirname(script_path)
        command = [f'{self.venv_path}/bin/python3', script_path] + list(args)
        return self.run_command(command,cwd=script_dir,env=env)
     def run_command(self, command, shell=False,cwd=None,env=None) -> Tuple[int, str]:
      # 执行命令
      result = subprocess.run(command, shell=shell, capture_output=True, text=True,cwd=cwd,env=env)
      print(f"returncode:{result.returncode}")
     return result.returncode

通过script_path地址变量解析,添加所有的路径到环境变量中,然后给subprocess.run做继承,subprocess.run如果不继承的,每开一个会话,都是新的变量环境。

总结:

可能还有其他方法,但大体上找不到module的问题,大部分是路径变量问题,按照这个思路去解决就可以解决大部分类似问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值