ros2_python编程_多个文件python打包_目录拷贝_解决import错误问题ModuleNotFoundError

news2024/11/13 8:44:59

1.问题

ros2 python编写程序, 有多个python文件

  1. 如何打包多个python文件?
  2. 解决import错误问题
  3. 如何打包 有python目录结构的工程

1.ros2 多个python文件示例

代码目录结构, gitee 在线代码

tree 7_multi_file_setup/
7_multi_file_setup/
├── file1.py
├── main_node.py

file1.py

file1_config={"lili":123, "makr": 222}

main_node.py
导入file.py 的 file1_config文件

# 导入本地模块
from file1 import *

def main():
    print("file1_config:", file1_config)

if __name__ == "__main__":
    main()

setup.py

from setuptools import find_packages, setup

package_name = '7_multi_file_setup'

setup(
    name=package_name,
    version='0.0.0',
    packages=find_packages(exclude=['test']),
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='liuj',
    maintainer_email='lj1637664504@outlook.com',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            'main_node = 7_multi_file_setup.main_node:main',
        ],
    },
)

2.运行错误: import error "No module named ‘file1’ "

编译: colcon build --packages-select 7_multi_file_setup
source install/setup.bash
ros2 run 7_multi_file_setup main_node

Traceback (most recent call last):
  File "/home/liuj/3_work/7_ros-robot-example/ros2/install/7_multi_file_setup/lib/7_multi_file_setup/main_node", line 33, in <module>
    sys.exit(load_entry_point('7-multi-file-setup==0.0.0', 'console_scripts', 'main_node')())
  File "/home/liuj/3_work/7_ros-robot-example/ros2/install/7_multi_file_setup/lib/7_multi_file_setup/main_node", line 25, in importlib_load_entry_point
    return next(matches).load()
  File "/usr/lib/python3.10/importlib/metadata/__init__.py", line 171, in load
    module = import_module(match.group('module'))
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/home/liuj/3_work/7_ros-robot-example/ros2/install/7_multi_file_setup/lib/python3.10/site-packages/7_multi_file_setup/main_node.py", line 2, in <module>
    from file1 import *
ModuleNotFoundError: No module named 'file1'
[ros2run]: Process exited with failure 1

3.问题原因: ros2 run 程序的 import 模块路径, 与 ros2工程路径不一致

main_node.py 打印 import sys.path导入模块路径

import sys

def show_ros_module_import_path():
    # 获取当前脚本所在的目录
    print("ros2 import module path:")
    for path in sys.path:
        print(path)
show_ros_module_import_path()

# 导入本地模块
from file1 import *

def main():
    print("file1_config:", file1_config)

if __name__ == "__main__":
    main()

3.1 ros2 run 打印 import module 导入模块路径结果
ros2 run 7_multi_file_setup main_node

ros2 import module path:
/home/liuj/3_work/7_ros-robot-example/ros2/install/7_multi_file_setup/lib/7_multi_file_setup
/home/liuj/3_work/7_ros-robot-example/ros2/install/7_multi_file_setup/lib/python3.10/site-packages
/opt/ros/humble/lib/python3.10/site-packages
/opt/ros/humble/local/lib/python3.10/dist-packages
/usr/lib/python310.zip
/usr/lib/python3.10
/usr/lib/python3.10/lib-dynload
/home/liuj/.local/lib/python3.10/site-packages
/usr/local/lib/python3.10/dist-packages
/usr/lib/python3/dist-packages

3.2 实际的文件路径

tree install/7_multi_file_setup/
install/7_multi_file_setup/
├── lib
│ ├── 7_multi_file_setup
│ │ └── main_node
│ └── python3.10
│ └── site-packages
│ ├── 7_multi_file_setup
│ │ ├── file1.py
│ │ ├── main_node.py

在这里插入图片描述

4.问题小结

  • ros2 run 程序 import 导入模块路径: /home/liuj/3_work/7_ros-robot-example/ros2/install/7_multi_file_setup/lib/python3.10/site-packages
  • 实际文件路径: /home/liuj/3_work/7_ros-robot-example/ros2/install/7_multi_file_setup/lib/python3.10/site-packages/7_multi_file_setup/file1.py
  • sys.path import路径 与 实际 ros2/install/package 代码路径不一致

2.解决方法

解决方案1: 拷贝 python 代码到 import 路径

ros2 install安装路径: ros2/install/package/lib/package
示例安装路径: ros2/install/7_multi_file_setup/lib/7_multi_file_setup

修改setup.py, 拷贝python代码到 import路径
setup.py

++ import os
from glob import glob
from setuptools import find_packages, setup

    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
++      (os.path.join('lib', package_name), glob('7_multi_file_setup/*.py')),
    ],
    install_requires=['setuptools'],
    zip_safe=True,

验证测试
编译: colcon build --packages-select 7_multi_file_setup

打包路径: ls install/7_multi_file_setup/lib/7_multi_file_setup/
2_添加模块路径_append_module_dir.py file1.py main_node main_node.py

运行结果: ros2 run 7_multi_file_setup main_node

file1_config: {‘lili’: 123, ‘makr’: 222}

解决方案2: sys.path 添加 install/package/lib/sitepackage代码路径

在ros2 python代码, 添加本地模块之前, 加入下面的函数

import os
import sys

def ros_append_module_dir():
    # 获取当前脚本的绝对路径
    script_path = os.path.abspath(__file__)
    # 获取当前脚本所在的目录
    script_dir = os.path.dirname(script_path)
    sys.path.append(script_dir)

ros_append_module_dir()

# 重要
# 重要
# 重要
# 导入本地模块之前

重要:

  1. ros_append_module_dir() 添加到本地模块之前
  2. ros_append_module_dir() 添加到本地模块之前
  3. ros_append_module_dir() 添加到本地模块之前
  4. ros_append_module_dir() insert before import local_module

原理解析:
在这里插入图片描述
本质是将 ros2 run package main_node --> main_node.py 文件路径添加到 sys.path中

3.python代码目录拷贝

如下, 代码目录中有 protobuf/ 目录, 如何拷贝目录
tree -L 7_multi_file_setup/

7_multi_file_setup/
├── main_node.py
├── protobuf
│ ├── websocket.py
│ └── websocket.proto

解决方法
setup.py

    data_files=[
        ('share/ament_index/resource_index/packages',['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
        (os.path.join('share', package_name), glob('launch/*_launch.py')),
++        (os.path.join('lib', package_name,'protobuf'), glob('network_proxy/protobuf/*.py')),
    ],

打包安装目录:

install/7_multi_file_setup/lib/7_multi_file_setup/protobuf/websocket.py

4.推荐方案 与 总结

1.推荐方案

个人推荐使用 解决方案1: 拷贝代码到import路径
理由:

  1. 无需修改源代码
  2. 解决 带 ros2 python 多个子目录结构时, site-packages 不打包子目录的问题

缺点:
4. install 目录代码多拷贝一份, 安装包文件体积变大

疑问:
是否有其它更优解决方法?

  1. 不修改源码, 只修改配置项

2.总结

  1. 要熟悉python import 与 sys.path 之间的关系
  2. 要熟悉setup.py 如何打包

个人签名
一个linux-网络-系统-固件-内核驱动-嵌入式-机器人开发工程师

个人微信
微信名片

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

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

相关文章

飞书怎么关联任意两段话

最近开始用飞书记文档&#xff0c;体验实在是非常的丝滑&#xff0c;对我来说感觉没有找到更好的竞品了。废话不多说&#xff0c;接下来简单介绍一下怎么关联任意两段话吧。 首先说明&#xff0c;关联可以单向&#xff0c;也可以双向。 直接举例。 我想要将蓝字关联到最下面的…

国标GB28181视频监控EasyCVR视频汇聚平台国标注册被陌生IP入侵如何处理?

GB28181国标/GA/T1400协议/安防综合管理系统EasyCVR视频汇聚平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入与汇聚管理。智慧安防/视频存储/视频监控/视频汇聚EasyCVR平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级…

Java基础(包装类)

文章目录 前言 一、包装类的概述 二、自动拆装箱 三、128陷阱&#xff08;面试重点&#xff09; 四、自动拆装箱例题分析 前言 该篇文章创作时参考查阅了如下文章 Java种的包装类 Java包装类&#xff08;自动拆装箱&#xff09; Java--自动拆箱/装箱/实例化顺序/缓存…

第三期书生大模型实战营之茴香豆工具实践

文章目录 基础任务作业记录1. 环境准备2. 模型准备3. 修改配置文件4. 知识库创建6. 启动茴香豆webui 基础任务 在 InternStudio 中利用 Internlm2-7b 搭建标准版茴香豆知识助手&#xff0c;并使用 Gradio 界面完成 2 轮问答&#xff08;问题不可与教程重复&#xff0c;作业截图…

IDEA2023版本创建SSM项目框架

按图中红色数字顺序&#xff0c;先点击Maven&#xff0c;设置该项目为maven构建管理的项目&#xff0c;然后点击create进行项目创建 配置该项目的相关maven信息&#xff0c;按下图顺序进入到maven配置页面后进行本地maven相关信息配置。 创建web模块依次按下图中顺序进行点击 配…

朴世龙院士团队《Global Change Biology 》精确量化全球植被生产力对极端温度的响应阈值!

本文首发于“生态学者”微信公众号&#xff01; 随着全球气候变暖的加剧&#xff0c;极端温度事件对陆地生态系统的影响日益显著。植被作为生态系统的重要组成部分&#xff0c;其生产力对温度变化的响应尤为敏感。然而&#xff0c;关于极端温度如何以及在何种程度上影响植被生产…

TCP三次握手过程详解

三次握手过程&#xff1a; 客户端视角&#xff1a; 1.客户端调用connect&#xff0c;开启计时器&#xff0c;发送SYN包&#xff0c;如果重传超时&#xff0c;认为连接失败 2.如果收到服务端的ACK&#xff0c;则进入ESTABLISHED状态 3.清除重传计时器&#xff0c;发送ACK&…

windows权限维持汇总

Windows 权限维持 一、文件层面 1&#xff09;attrib 使用 Attrib s a h r 命令 s&#xff1a;设置系统属性&#xff08;System&#xff09; a&#xff1a;设置存档属性&#xff08;Archive&#xff09; h&#xff1a;设置隐藏属性&#xff08;Hidden&#xff09; r&#…

深度学习基础--11个专题带你入门Pytorch上

目的 本专栏更新深度学习基础&#xff0c;包括pytorch、tensorflow的使用以及CNN、RNN、yolo、GAN、LSTM、Transformer等神经网络的理论基础 前言 Pytorch是最常用的深度学习框架&#xff0c;里面包含了大量关于构建神经网络及其运算的APIPytorch基础入门分为上下两篇文章&am…

基于事件总线EventBus实现邮件推送功能

什么是事件总线 事件总线是对发布-订阅模式的一种实现。它是一种集中式事件处理机制&#xff0c;允许不同的组件之间进行彼此通信而又不需要相互依赖&#xff0c;达到一种解耦的目的。 关于这个概念&#xff0c;网上有很多讲解的&#xff0c;这里我推荐一个讲的比较好的&#x…

光伏设计时要画出哪些模型?

在光伏系统的设计中&#xff0c;为了确保项目的顺利实施与高效运行&#xff0c;设计师需要绘制多种模型来综合考虑各种因素&#xff0c;包括参照物、障碍物以及楼顶配房等。这些模型不仅有助于预测光伏系统的发电效率&#xff0c;还能帮助规划最佳的安装布局&#xff0c;减少阴…

碎片笔记|Computer Journal 期刊投稿注意事项

前言&#xff1a;3月份把之前做的一篇工作转投到了computer journal&#xff0c;8月7号来信说我投稿的工作之前因为挂在arXiv上&#xff0c;因此和正常的投稿要求不太一致&#xff0c;需要更换投稿方式&#xff0c;编辑提供了两种选择如下。 The first choice is to keep your …

python 接口自动化测试中的高阶函数!

高阶函数简介 高阶函数是指接受函数作为参数或者返回函数作为结果的函数。在 Python 中&#xff0c;有许多内置的高阶函数&#xff0c;如 map, filter, reduce 等&#xff0c;它们可以极大地简化代码并提高代码的可维护性。 summer camp map 函数 map 函数接收一个函数和一个…

Jmeter下载、配置环境变量

Jmeter下载 下载地址&#xff1a;Apache JMeter - Download Apache JMeter 下载后无需安装&#xff0c;解压后即可使用。解压后目录如下 配置环境变量 JMETER_HOME 环境变量Path %JMETER_HOME%\bin 环境变量CLASSPATH %JMETER_HOME%\lib 验证是否配置成功 在cmd命令窗中 输入…

玄机又成国漫首创!IP与AI融合,凭实力火出圈

现在国漫越来越卷了&#xff0c;不仅卷制作质量&#xff0c;还卷各种花式联动。最近玄机科技和百度文库联合举办的AI漫画大赛圆满结束&#xff0c;这还是国内的IP第一次和AI技术融合&#xff0c;而且产出了不少好作品。下面就一起来看看吧&#xff01; 提到玄机科技&#xff0c…

机器人笛卡尔空间轨迹规划-直线差补和圆弧差补

上一文&#xff0c;我们讨论了三次多项式和五次多项式的差补算法&#xff0c;那么这边文章具体讨论一下笛卡尔空间轨迹规划的直线差补和圆弧差补。 步骤 &#xff08;1&#xff09;知道起始点和终止点的位姿&#xff0c;和速度信息。 &#xff08;2&#xff09;根据两点能确定一…

湖仓一体大数据平台:开启企业数据管理新时代(附Hudi案例)

湖仓一体大数据平台&#xff1a;开启企业数据管理新时代&#xff08;附Hudi案例&#xff09; 前言湖仓一体大数据平台 前言 在当今数字化浪潮汹涌澎湃的时代&#xff0c;数据如同企业发展的珍贵宝藏&#xff0c;而如何高效地挖掘、管理和利用这些宝藏&#xff0c;成为了企业在…

详细的Anaconda安装jupyter notebook与使用

jupyter notebook概念 Jupyter Notebook 是一种交互式计算环境&#xff0c;广泛用于数据分析、机器学习和编程学习等领域。 一、pip安装 打开 Anaconda Prompt 输入&#xff1a;pip install jupyter notebook pip install jupyter notebook 安装成功画面 输入命令&#xff1…

Git实战精粹

一、快速入门 1. 什么是Git Git是一个分布式的版本控制软件。 软件&#xff0c;类似于QQ、office、dota等安装到电脑上才能使用的工具版本控制&#xff0c;类似于毕业论文、写文案、视频剪辑等&#xff0c;需要反复修改和保留原历史数据分布式 文件夹拷贝本地版本控制集中式…

SpringMVC基于注解的使用

SpringMVC基于注解的使用 首先导入spring-mvc的依赖文件 然后配置上篇文章的web.xml文件 在配置上篇文章的spring-mvc.xml文件 创建一个ParamsContrller类写个方法方法里面的参数名可以用到客户端请求&#xff0c;且可以为参数写任意类型 如果想改参数名可以用RequestParam为…