python模块引入问题和解决方案_真方案不骗人

news2025/7/31 4:40:26

1.pycharm运行python脚本的过程

使用pycharm等编辑器run/debug运行python脚本时,编辑器会通过本地python命令全路径执行脚本,例如

D:\DevelopTools\Python\python.exe D:/Codes/一长串路径/bbss_nature_python/demo/test_no_param_in.py

并且会在python系统环境命令路径prepend即append first拼接启动脚本的绝对目录路径和脚本依赖的绝对目录路径,例如

print ("sys.path")
['D:\\Codes\\一长串路径\\bbss_nature_python\\demo', 'D:\\Codes\\一长串路径\\bbss_nature_python', ...]

这是由于pycharm编辑器run/debug配置中自动定义了全路径工作目录、全路径启动脚本、环境命令拼接等,如下图

2.python命令运行python脚本常见模块引入问题

例1

D:\Codes\cust\rycust\bbss_nature_cust_2021-2030\bbss_nature_cust>python bbss_nature_python/demo/test_no_param_in.py

在以上工作目录,使用相对路径运行python脚本,报错如下(绝对路径也是同样的报错)
Traceback (most recent call last):
   File "D:\Codes\cust\rycust\bbss_nature_cust_2021-2030\bbss_nature_cust\bbss_nature_python\demo\test_no_param_in.py", line 17, in <module>
    from common_code import ScriptReturnClz, _object2json_str
ModuleNotFoundError: No module named 'common_code'

例2

D:\Codes\cust\rycust\bbss_nature_cust_2021-2030\bbss_nature_cust>python bbss_nature_python/demo/test_no_param_in.py

在以上工作目录,使用相对路径运行python脚本,报错如下(绝对路径也是同样的报错)
Traceback (most recent call last):
   File "D:\Codes\cust\rycust\bbss_nature_cust_2021-2030\bbss_nature_cust\bbss_nature_python\demo\test_no_param_in.py", line 18, in <module>
    from ..common_code import ScriptReturnClz, _object2json_str
ImportError: attempted relative import with no known parent package

 

3.python命令运行python脚本模块引入问题的解决方案

Python在引用库文件时,会自动从python安装目录的Lib子目录等目录查找依赖,默认查找路径可以通过命令print(sys.path)查看

print ("sys.path")

['D:\\Codes\\cust\\rycust\\bbss_nature_cust_2021-2030\\bbss_nature_cust\\bbss_nature_python\\demo', 'D:\\DevelopTools\\Python\\python310.zip', 'D:\\DevelopTools\\Python\\DLLs', 'D:\\DevelopTools\\Python\\lib', 'D:\\DevelopTools\\Pyt

hon', 'D:\\DevelopTools\\Python\\lib\\site-packages']

可以看到,python命令执行一个python脚本前,会在sys.path数组第一位拼接启动脚本的目录绝对路径

测试用例目录文件树形图如下

 

3.1模块和当前脚本在同一目录下

在引用自定义模块时,如果模块和当前脚本在同一目录下,引入的时候,有以下几种方式:

1.直接模块名引入√【不建议】

from test_with_param_in import _print_json_param

此时,pycharm编辑器会告警,但python、pycharm运行都是正常的

可以选择忽略告警(告警右键选择ignore)

2.包名.模块名引入√【推荐,参见后文最佳方案】

from demo.test_with_param_in import _print_json_param

此时,pycharm编辑器不会告警,但python运行会报错

Traceback (most recent call last):

  File "D:\Codes\cust\rycust\bbss_nature_cust_2021-2030\bbss_nature_cust\bbss_nature_python\demo\test_no_param_in.py", line 16, in <module>

    from demo.test_with_param_in import _print_json_param

ModuleNotFoundError: No module named 'demo'

此时需要引入缺少的模块所在的目录的绝对路径,如下

current_script_dir = os.path.split(os.path.realpath(__file__))[0]
current_script_dir_parent = os.path.split(current_script_dir)[0]
sys.path.insert(0, current_script_dir_parent)

3..模块名引入×【不可行】

from .test_with_param_in import _print_json_param

此时,pycharm编辑器不会告警,但python运行会报错

Traceback (most recent call last):

  File "D:\Codes\cust\rycust\bbss_nature_cust_2021-2030\bbss_nature_cust\bbss_nature_python\demo\test_no_param_in.py", line 16, in <module>

    from .test_with_param_in import _print_json_param

ImportError: attempted relative import with no known parent package

无解决方案

3.2模块和当前脚本在不同目录下

如果模块和当前脚本不在同一目录下,必须指定模块路径,可以在当前脚本中import sys然后

通过sys.path.append(‘待引入的模块路径’)或者sys.path.insert(0,‘待引入的模块路径’)拼接的方式加入python系统命令路径,建议insert

待引入的模块路径,应该使用绝对(abs)路径,对于相对路径,python会直接拼接工作目录+相对路径生成绝对路径,拼接后的绝对路径是错误的(除非工作目录本身就是启动脚本的目录)

脚本内容:

# 当前脚本abs目录
current_script_dir = os.path.split(os.path.realpath(__file__))[0]
# 当前脚本目录的上级abs目录(对于本测试用例即为待引入模块的abs目录)
current_script_dir_parent = os.path.split(current_script_dir)[0]
# 待引入模块common_code的abs目录加入系统环境命令路径数组

sys.path.insert(0, current_script_dir_parent)
print("print (\"sys.path\")")
print(sys.path)

# 引入自定义模块common_code【注意,代码中必须先添加路径之后才能引入】

from common_code import ScriptReturnClz, _object2json_str

命令:

 D:\Codes\cust\rycust\bbss_nature_cust_2021-2030\bbss_nature_cust>python bbss_nature_python/demo/test_no_param_in.py

运行结果:

print ("sys.path")

['D:\\Codes\\cust\\rycust\\bbss_nature_cust_2021-2030\\bbss_nature_cust\\bbss_nature_python', 'D:\\Codes\\cust\\rycust\\bbss_nature_cust_2021-2030\\bbss_nature_cust\\bbss_nature_python\\demo', 'D:\\DevelopTools\\Python\\python310.zi

p', 'D:\\DevelopTools\\Python\\DLLs', 'D:\\DevelopTools\\Python\\lib', 'D:\\DevelopTools\\Python', 'D:\\DevelopTools\\Python\\lib\\site-packages']

4.python命令运行python脚本模块引入的最佳方案

4.1复杂工程的依赖遍历问题

当待引入的模块和当前脚本在不同目录下时,需要在环境变量中加入待引入模块目录的绝对路径,每个类似的启动脚本(即python命令执行的脚本)都需要编写很多类似的模板代码,而且由于依赖的传递性,可能无法简单地遍历出所有的自定义依赖模块

4.2 IDE的依赖默认引入方式

复杂依赖的python脚本,尤其是系统级规模化的python工程,通常使用pycharm等IDE编写。IDE会创建python工程,并且以工程目录为工作目录,在编写py脚本时,从工作目录开始查找自定义模块,自动补齐工作目录下的相对路径。另外,在打包python工程时,也是从工程目录开始。因此,使用IDE的默认的补全模块路径的依赖引入方式是最优选择

4.3多工程依赖的解决方案

不同于java微服务子工程之间的依赖引用,python没有子工程概念,只有一个完整的未拆分的工程。如果两个工程之间有模块依赖关系,则需要同时部署两个工程,并使用绝对路径引入另一个工程的工程目录,然后从工程目录开始引入所需模块。对于常用的自定义的基础依赖,也可以打包发布到公有源或私有源,直接install引入模块。从工程角度考虑,需要区分模块的命名空间,应采用和java包名类似的方式,以组织或个人的标识创建模块总包

4.4找到python工程的工程目录【方案本案】

鉴于IDE的依赖引入方式,只要将python工程的工程目录加入sys.path,则工程内的任何一个pycharm可成功运行的启动脚本都可以用python命令成功运行

怎样可以方便地找到一个python工程的工程目录?这取决于一个工程有多少启动脚本,以及每个启动脚本的位置

如果一个python工程只有一个启动脚本,比如一个python文件服务器,那么这个脚本应该直接放在工程一级目录下(如下图中工程目录为D:\tmp\python,start.py为启动脚本),这样可以顺利找到当前工程中的所有自定义依赖,这是因为启动脚本路径自动拼接环境变量

如果一个python工程有多个启动脚本,并且不是都在工程目录下,比如一个python计算工具包,那么每一个启动脚本的全局代码块都需要添加工程目录,举例如下

# 当前脚本abs目录
current_script_dir = os.path.split(os.path.realpath(__file__))[0]
# 当前脚本目录的上级abs目录(对于本测试用例即为python工程abs目录,如果不是,可继续上溯)
current_script_dir_parent = os.path.split(current_script_dir)[0]
# python工程路径
python_project_dir = current_script_dir_parent
if sys.path[0] != python_project_dir:
    sys.path.insert(0, python_project_dir)
    print("添加工程目录:" + python_project_dir)
    print("print (\"sys.path\")")
    print(sys.path)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/394500.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自动化框架如何搭建?让10年阿里自动化测试老司机帮你搞定!自动化测试脚本怎么写?

一、何为框架&#xff1f;何为自动化测试框架&#xff1f; 无论是日常技术交流&#xff0c;还是在自动化测试实践中&#xff0c;经常会听到一个词叫&#xff1a;框架。之前对“框架”这个词知其然不知其所以然。现在看过一些资料以及加上我自己的一些实践有了我自己的一些看法…

PowerJob中的Vert.x的应用,是点睛之笔还是大材小用?我感觉有点故意炫技啊

这是一篇为了参加活动写得文章&#xff0c;不知道为什么&#xff0c;写得时候网络巨差&#xff0c;我是顶着闹心发上来的&#xff0c;最后大家女神节快乐。 最近难得忙了一下&#xff0c;领导让我从Vert.x和lagom中技术选型&#xff0c;因为lagom是scala写得&#xff0c;我虽然…

2023高质量设计竞赛汇总,想证明自己实力的快来

对于设计师来说&#xff0c;参加设计比赛不仅能够提升自己的设计能力&#xff0c;也是一条证明实力最好的捷径。小编也收集整理了不少近期设计大赛&#xff0c;分别标注了截止日期和官网等&#xff0c;宝子们记得码住收藏&#xff0c;赶紧SHOW起来&#xff01;优酷X站酷 一千零…

湖南媒体资源有哪些?湖南媒体邀约怎么做?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 湖南位于中国中南部&#xff0c;以其美丽的自然风光、丰富的历史文化和独特的湖湘文化而著名&#xff0c;拥有丰富的媒体资源。以下是一些湖南省的媒体资源&#xff1a; 1.湖南日报社: …

Spark 应用调优

Spark 应用调优人数统计优化摇号次数分布优化Shuffle 常规优化数据分区合并加 Cache优化中签率的变化趋势中签率局部洞察优化倍率分析优化表信息 : apply : 申请者 : 事实表lucky : 中签者表 : 维度表两张表的 Schema ( batchNum&#xff0c;carNum ) : ( 摇号批次&#xff0c…

Java基础——Lambda表达式

一、函数式编程思想概述https://www.runoob.com/java/java8-lambda-expressions.html在数学中&#xff0c;函数就是有输入量、输出量的一套计算方案&#xff0c;也就是“拿数据做操作”面向对象强调“必须通过对象的形式来做事情”&#xff0c;做事情之前首先要创建一个对象函数…

B站游戏推广,怎样查看B站游戏推广榜数据?

近年来&#xff0c;B站发展得越来越大&#xff0c;越来越多的游戏商也加入B站进行推广&#xff0c;那么作为游戏运营商&#xff0c;怎样查看游戏在B站上的推广数据呢&#xff1f;游戏排行榜游戏商业推广榜包含视频推广榜、直播推广榜&#xff0c;按照日榜、周榜、月榜&#xff…

【Linux 网络编程1】使用UDP/TCP编写套接字,多进程/多线程版本的TCP编写的套接字,将套接字封装

目录 1.学习网络编程前的一些基础知识 2.UDP(user datagram protocol)协议的特点 3.使用有UPD编写套接字 4.使用TCP编写套接字 4.2.TCP客服端 4.3.TCP服务器端 4.4.单进程版本&#xff08;没有人会使用&#xff09; 4.5.多进程版本 4.6.多线程版本 5.把套接字封装 1…

扬帆优配|2600亿新能源巨头狂飙!外资唱多中国:再涨15%

全国停摆的危机&#xff0c;正在迫临法国。 大停工正在将法国推向风险境地。法国政府估计&#xff0c;当地时间3月7日&#xff0c;将迸发全国大型停工游行。法国总工会宣告&#xff0c;到时将让全法国停摆。法国担任交通业务的部长级代表克莱蒙博讷正告称&#xff0c;7日将成为…

JavaScript 混淆技术

根据JShaman&#xff08;JShaman是专业的JavaScript代码混淆加密网站&#xff09;提供的消息&#xff0c;JavaScript混淆技术大体有以下几种&#xff1a; 变量混淆 将带有JS代码的变量名、方法名、常量名随机变为无意义的类乱码字符串&#xff0c;降低代码可读性&#xff0c;如…

原神 Android 教程 —安卓版

准备材料 一台能读写 /system 分区的 Android 手机(或:一台安装了 Magisk 的 Android 手机) 有人搞出来免root端了,此条件不再必须私服客户端

数据同步工具Sqoop

大数据Hadoop之——数据同步工具SqoopSqoop基本原理及常用方法 1 概述 Apache Sqoop&#xff08;SQL-to-Hadoop&#xff09;项目旨在协助RDBMS&#xff08;Relational Database Management System&#xff1a;关系型数据库管理系统&#xff09;与Hadoop之间进行高效的大数据交…

HStream Console、HStreamDB 0.14 发布

近两个月&#xff0c;HStreamDB 相继发布了 0.13 和 0.14 版本&#xff0c;包含多项已知问题修复。同时&#xff0c;我们也发布了全新的 HStream Console 组件&#xff0c;为 HStreamDB 带来了简洁友好的图形化管理界面&#xff0c;将帮助用户更轻松地使用和管理 HStreamDB. H…

LinqConnect兼容性并支持Visual Studio 2022版本

LinqConnect兼容性并支持Visual Studio 2022版本 现在支持Microsoft Visual Studio 2022版本17.5预览版。 添加了Microsoft.NET 7兼容性。 共享代码-共享相同的代码&#xff0c;以便在不同的平台上处理数据。LinqConnect是一种数据库连接解决方案&#xff0c;适用于不同的基于.…

Ubuntu下安装Docker

大家好&#xff0c;我是中国码农摘星人。 欢迎分享/收藏/赞/在看&#xff01; 文章目录1 安装Docker1.1 使用官方安装脚本自动安装 &#xff08;仅适用于公网环境&#xff09;1.2 手动安装帮助1.2.1 Ubuntu 14.04 16.04 (使用apt-get进行安装)2 安装校验3 镜像加速器3.1 安装&a…

在 k8S 中搭建 SonarQube 7.4.9 版本(使用 PostgreSQL 数据库)

本文搭建的 SonarQube 版本是 7.4.9-community&#xff0c;由于在官方文档中声明 7.9 版本之后就不再支持使用 MySQL 数据库。所以此次搭建使用的数据库是 PostgreSQL 11.4 版本。 一、部署 PostgreSQL 服务 1. 创建命名空间 将 PostgreSQL 和 SonarQube 放在同一个命名空间…

Docker(二)

5.容器数据卷 1.什么是容器数据卷 docker理念回顾 将应用和环境打包成一个镜像&#xff01; 数据&#xff1f;如果数据都在容器中&#xff0c;那么我们容器删除&#xff0c;数据就会丢失&#xff01;需求&#xff1a;数据可以持久化 MySQL&#xff0c;容器删了&#xff0c…

都工作3年了,怎么能不懂双亲委派呢?(带你手把手断点源码)

&#x1f497;推荐阅读文章&#x1f497; &#x1f338;JavaSE系列&#x1f338;&#x1f449;1️⃣《JavaSE系列教程》&#x1f33a;MySQL系列&#x1f33a;&#x1f449;2️⃣《MySQL系列教程》&#x1f340;JavaWeb系列&#x1f340;&#x1f449;3️⃣《JavaWeb系列教程》…

c盘怎么清理到最干净?有什么好的清理方法

c盘怎么清理到最干净?有什么好的清理方法&#xff1f;清理C盘空间是电脑维护的重要步骤之一。C盘是Windows操作系统的核心部分&#xff0c;保存了许多重要的系统文件&#xff0c;因此空间不足会影响计算机的性能和稳定性。下面是一些清理C盘空间的方法 一.清理临时文件 在使用…

【Java学习笔记】10.条件语句 - if...else及switch case 语句

前言 本章介绍Java的条件语句 - if…else和switch case 语句。 Java 条件语句 - if…else Java 中的条件语句允许程序根据条件的不同执行不同的代码块。 一个 if 语句包含一个布尔表达式和一条或多条语句。 语法 if 语句的语法如下&#xff1a; if(布尔表达式) {//如果布…