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
相关产品推荐
相关产品推荐

