You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python -m执行serial.tools.list_ports时的调用文件与输出逻辑

解答

-m参数运行逻辑与本次调用的实际文件

python -m <模块路径>的执行规则如下:

  • 按顺序遍历sys.path下的路径查找目标模块
  • 若目标是单文件模块(.py文件),直接将该文件作为__main__入口执行
  • 若目标是Python包(含__init__.py的目录),则查找包路径下对应层级的模块/子包,最终执行目标模块的代码;如果目标路径本身是包,则执行包内的__main__.py作为入口。

找不到serial.py是正常的:serial是pyserial库的包目录,不是单文件模块,你看到的serialcli.py、serialutil.py都是包内的附属功能文件。
执行python3 -m serial.tools.list_ports时实际访问的文件按加载顺序为:

  • serial/__init__.py:serial包的初始化文件
  • serial/tools/__init__.py:serial下tools子包的初始化文件
  • serial/tools/list_ports.py:本次命令的实际执行入口,命令的所有逻辑都从这个文件启动。

可执行以下代码直接定位这个文件的绝对路径:

import serial.tools.list_ports
print(serial.tools.list_ports.__file__)

通常该文件位于Python安装目录的dist-packages或site-packages路径下。

命令输出的生成原因

输出和-m参数本身没有特殊绑定,是list_ports.py内置的入口逻辑触发的:该文件末尾写了标准的入口判断块:

if __name__ == "__main__":
    # 串口枚举、逐行打印端口、打印端口总数的逻辑

只有当文件被作为主程序直接运行(包括-m调用、直接运行该py文件两种场景)时,这个判断块内的代码才会执行。如果是在自己的代码中import serial.tools.list_ports,此时该模块的__name__属性为包路径而非__main__,打印逻辑不会触发,自然没有输出。

Python代码内直接调用该功能的方法

无需调用shell命令,直接导入模块内置的枚举接口即可,示例代码:

from serial.tools.list_ports import comports

port_list = comports()
for port in port_list:
    print(port.device)
print(f"{len(port_list)} ports found.")

运行上述代码可以得到和命令行执行完全一致的输出,还可以通过port对象获取串口描述、硬件ID等额外信息。


内容的提问来源于stack exchange,提问作者Micklos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 03:42:18