python模块引入问题和解决方案_真方案不骗人
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\\Python', '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.zip', '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)
相关文章:
python模块引入问题和解决方案_真方案不骗人
1.pycharm运行python脚本的过程 使用pycharm等编辑器run/debug运行python脚本时,编辑器会通过本地python命令全路径执行脚本,例如 D:\DevelopTools\Python\python.exe D:/Codes/一长串路径/bbss_nature_python/demo/test_no_param_in.py 并且会在pyth…...
Read book Netty in action(Chapter X)--Unit Testing
序言 ChannelHandler 是Netty 应用程序的关键元素,所以彻底地测试它们应该是你的开发过程的一个标准部分。最佳实践要求你的测试不仅要能够证明你的实现是正确的,而且还要能够很容易地隔离那些因修改代码而突然出现的问题。这种类型的测试叫作单元测试。…...
Appium+Python连接真机、跳过登录页、Unexpected error while obtaining UI hierarchy问题
Appium连接真机 使用数据线连接电脑,然后选择文件传输方式 打开手机设置拉至底部,点击关于手机,连续点击7次版本号打开开发者模式 点击设置中的系统与更新,找到开发者选项----> 打开USB调试即可 在终端中输入adb devices确定…...
ES6模块化
目录 一、什么是 ES6 模块化规范 二、ES6 模块化的基本语法 2.1默认导出 2.1默认导入 2.1 注意事项 2.2按需导出 2.2按需导入 2.2按需导出与按需导入的注意事项 2.3直接导入并执行模块中的代码 一、什么是 ES6 模块化规范 ES6 模块化规范是浏览器端与服务器端通用的…...
201809-3 CCF 元素选择器 满分题解(超详细注释代码) + 解题思路(超详细)
问题描述 解题思路 根据题意可以知道在查询中可以分为两种情况 第一种是查询一个标签选择器或者id选择器(可以称为一级查询) 第二种就是存在大于两级的查询(可以称为多级查询) 显然第一种查询需要存储每一种元素在内容中所有出现…...
证书拓展域(1)
证书拓展定义了数字证书的标准拓展,每个拓展域GB/T 16264.8-200X中定义的一个OID相关。 这些OID都是id-ce的成员,其定义如下: id-ce OBJECT IDENTIFIER :: { joint-iso-ccitt(2) ds(5) 29 }1.证书策略 certificatePolicies 1.1 定义 本…...
浅谈ChatGPT 和 对AI 的思考
新世纪以来,人工智能作为一个非常热门话题,一直收到大众的广泛的关注。从一开始的图像的分类,检测,到人脸的识别,到视频分析分类,到事件的监测,到基于图片的文本生成,到AI自动写小说…...
NCRE计算机等级考试Python真题(十二)
第十二套试题1、以下关于程序设计语言的描述,错误的选项是:A.Python语言是一种脚本编程语言B.汇编语言是直接操作计算机硬件的编程语言C.程序设计语言经历了机器语言、汇编语言、脚本语言三个阶段D.编译和解释的区别是一次性翻译程序还是每次执行时都要翻…...
Java并发类库提供的线程池有哪几种? 分别有什么特点?
第21讲 | Java并发类库提供的线程池有哪几种? 分别有什么特点? 我在专栏第 17 讲中介绍过线程是不能够重复启动的,创建或销毁线程存在一定的开销,所以利用线程池技术来提高系统资源利用效率,并简化线程管理,…...
企业微信如何群发消息到客户群?
为提升工作效率,工作中,企业常常会借助企业微信的群发功能一键发送多个客户。那么企业微信如何群发消息呢? 其中成员个人支持群发消息到客户群,企业也可以创建内容提醒成员进行执行群发。 管理员支持在管理端或在手机端创建企业…...
【信号与系统笔记】第一章 绪论
1.1信号传输系统 信息传输的任务 将带有信息的信号,通过某种系统由发送者传送给接收者。 通信系统的组成 转换器:把消息转换为电信号或者把电信号还原成消息信道:信号传输的通道,广义上来说。发射机和接收机也可以是信道的一部分…...
[神经网络]DETR目标检测网络
一、概述 相较于传统目标检测,DETR是一种纯端到端的网络。它不再需要NMS(非极大值抑制,用于去除多余的预测框)和生成anchor。 DETR提出了一个新的目标函数(二分图匹配),这个函数可以强制网络输出一个独一无二的预测值&…...
【服务器管理】connection refused问题解决
简述 在配置服务器的时候,遇到了这个问题。我当时明明已经搭建好了服务,但是我在客户端比如手机上,却怎么都连不上服务器。看日志的话显示的是connection refuesed timeout 这种情况,大概率是服务器的端口没有被打开。 我们只需…...
2023_华为OD机试真题_Python_047_整理扑克牌
整理扑克牌 题目描述 给定一组数字,表示扑克牌的牌面数字,忽略扑克牌的花色,请按如下规则对这一组扑克牌进行整理: 步骤1. 对扑克牌进行分组,形成组合牌,规则如下: 当牌面数字相同张数大于等于4时,组合牌为“炸弹”;3张相同牌面数字 + 2张相同牌面数字,且3张牌与2…...
吐血整理,自动化测试pytest测试框架,资深测试带你少走弯路......
目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 Pytest框架详解 py…...
SAP BASE64加密及解密
简介:BASE64是一种编码方法,它是一种基于用64个可打印字符来表示二进制数据的表示方法,主要应用于数据存储,传输,打印它是用64个可打印字符表示二进制所有数据方法。由于2的6次方等于64,所以可以用每6个位元…...
【页面无响应】Web页面经常无响应前端如何定位与优化(已解決)
【写在前面】客户现场应用我们的系统时候,发现用着用着就出现1个页面无响应现象,给客户带来极其不好的体验,尤其是当重要工作汇报演示时,就给我看无响应,浏览器崩溃?这样对产品的发展无疑是致命的伤&#x…...
隐私计算 FATE - 多分类神经网络算法测试
一、说明 本文分享基于 Fate 使用 横向联邦 神经网络算法 对 多分类 的数据进行 模型训练,并使用该模型对数据进行 多分类预测。 二分类算法:是指待预测的 label 标签的取值只有两种;直白来讲就是每个实例的可能类别只有两种 (0 或者 1)…...
Codeforces Round 853 (Div. 2)
Codeforces Round 853 (Div. 2) C. Serval and Toxels Arrays 思路: 求任意两个组合的元素个数。 注意到,其实每个元素都是独立的。他在任意组合的出现情况组成的贡献是可以分开讨论的。我们讨论元素x。假设x在m1个数组中出现了cnt次(一个…...
Ka频段需要更多带宽?
随着全球连接需求的增长,许多卫星通信(satcom)系统日益采用Ka频段,对数据速率的要求也水涨船高。目前,高性能信号链已经能支持数千兆瞬时带宽,一个系统中可能有成百上千个收发器,超高吞吐量数据速率已经成为现实。 另…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...
