Zhong__Python enumerate()

时间:2020.12.11

环境:Python3

目的:简单使用enumerate()

说明:

作者:Zhong QQ交流群:121160124 欢迎加入!

 

 

Python 内置函数enumerate()

描述

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

Python 2.3. 以上版本可用,2.6 添加 start 参数。

语法

以下是 enumerate() 方法的语法:

enumerate(sequence, [start=0])

参数

  • sequence -- 一个序列、迭代器或其他支持迭代对象。
  • start -- 下标起始位置。

返回值

返回 enumerate(枚举) 对象。

实例

# 定义一个包含季节的列表
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
print(list(enumerate(seasons)))  # [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]

# 下标从 1 开始
print(list(enumerate(seasons, start=1)))  # [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

# for 循环使用 enumerate
for i, season in enumerate(seasons, start=1):
    print(f"{i} -- {season}")

总结

在需要遍历可迭代对象获取索引和值时很适合使用

 

关注微信公众号

 

 

 

 

 

 

 

 

<think> 我们正在讨论udev_enumerate_new函数,该函数用于创建一个新的枚举器对象,用于扫描设备。 根据引用[1]中的信息,我们知道udev_enumerate_scan_xxx系列函数用于扫描/sys目录下与过滤器匹配的设备,并构建一个链表。 udev_enumerate_new是创建这样一个枚举器的第一步。 函数原型: struct udev_enumerate *udev_enumerate_new(struct udev *udev); 参数: udev: 由udev_new()创建的udev上下文对象。 返回值: 成功:返回一个指向udev_enumerate对象的指针。 失败:返回NULL。 功能: 创建一个新的枚举器对象,用于扫描系统中当前存在的设备。这个枚举器对象可以用来添加匹配条件(过滤器),然后执行扫描操作,最后获取设备列表。 使用步骤: 1. 创建udev上下文:使用udev_new()。 2. 创建枚举器:使用udev_enumerate_new(),传入udev上下文。 3. 添加匹配条件(可选):例如,使用udev_enumerate_add_match_subsystem()来指定子系统(如"usb")。 4. 扫描设备:调用udev_enumerate_scan_devices()或udev_enumerate_scan_subsystems()。 5. 获取设备列表:使用udev_enumerate_get_list_entry()获取链表的第一个条目。 6. 遍历链表:使用udev_list_entry_foreach()宏遍历每个条目,每个条目代表一个设备,可以通过udev_device_new_from_syspath()来创建设备对象。 7. 释放资源:使用udev_enumerate_unref()释放枚举器。 代码示例: 以下是一个简单的示例,展示如何使用udev_enumerate_new来枚举所有USB设备: ```c #include <libudev.h> #include <stdio.h> int main() { struct udev *udev = udev_new(); if (!udev) { fprintf(stderr, "无法创建udev上下文\n"); return 1; } // 创建枚举器 struct udev_enumerate *enumerate = udev_enumerate_new(udev); if (!enumerate) { fprintf(stderr, "无法创建枚举器\n"); udev_unref(udev); return 1; } // 添加匹配条件:只扫描USB子系统 udev_enumerate_add_match_subsystem(enumerate, "usb"); // 执行扫描 udev_enumerate_scan_devices(enumerate); // 获取设备链表 struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate); struct udev_list_entry *entry; // 遍历链表 udev_list_entry_foreach(entry, devices) { // 获取设备的syspath const char *syspath = udev_list_entry_get_name(entry); // 创建设备对象 struct udev_device *dev = udev_device_new_from_syspath(udev, syspath); if (dev) { // 获取设备信息,例如设备节点(如果有的话) const char *devnode = udev_device_get_devnode(dev); if (devnode) { printf("设备节点: %s\n", devnode); } // 获取其他属性,例如厂商ID和产品ID const char *idVendor = udev_device_get_sysattr_value(dev, "idVendor"); const char *idProduct = udev_device_get_sysattr_value(dev, "idProduct"); if (idVendor && idProduct) { printf(" 厂商ID: %s, 产品ID: %s\n", idVendor, idProduct); } udev_device_unref(dev); } } // 释放枚举器 udev_enumerate_unref(enumerate); udev_unref(udev); return 0; } ``` 注意事项: - 在使用枚举器之前,通常需要添加匹配条件(过滤器)来缩小扫描范围,否则将会枚举所有设备。 - 枚举器扫描完成后,返回的链表中的条目是设备在sysfs中的路径(syspath),我们可以通过这些路径创建设备对象(udev_device)。 - 遍历链表时,使用udev_list_entry_foreach宏可以方便地遍历每个条目。 - 每次调用udev_device_new_from_syspath都会创建一个新的设备对象,使用完后必须使用udev_device_unref释放。 - 整个枚举器对象使用完后,必须使用udev_enumerate_unref释放。 错误处理: 在创建枚举器或扫描设备时,如果失败,通常是因为内存不足或者参数无效。因此,应该检查每个步骤的返回值。 引用说明: 根据引用[1],枚举器扫描设备后返回一个链表,可以使用udev_list_entry_foreach遍历链表[^1]。 引用[2]中的代码展示了在Qt中如何使用udev监控USB设备,其中也用到了枚举器(GetUSBDevices方法)[^2]。 扩展:过滤器函数 除了添加子系统匹配,还可以使用其他函数添加更多匹配条件,例如: - udev_enumerate_add_match_sysattr: 按系统属性匹配(如属性idVendor的值) - udev_enumerate_add_match_property: 按设备属性匹配 - udev_enumerate_add_match_tag: 按标签匹配 相关问题: §§相关问题§§ 1. 如何通过udev_enumerate_add_match_sysattr过滤特定属性的设备? 2. 使用udev_enumerate_scan_subsystems与udev_enumerate_scan_devices有何区别? 3. 在遍历设备链表时,如何获取设备的更多详细信息(如序列号)? </think> ### `udev_enumerate_new()` 函数详解 #### ✅ 1. **功能概述** `udev_enumerate_new()` 是 Linux `libudev` 库的关键函数,用于创建**设备枚举器对象**。该对象提供系统设备的扫描和过滤能力,是设备管理的基础工具。主要功能包括: - 初始化设备扫描环境 - 支持基于子系统/属性/标签的设备过滤 - 构建设备链表用于后续遍历 - 与 `udev_monitor` 配合实现实时设备监控[^1][^2] #### ✅ 2. **函数原型** ```c #include <libudev.h> struct udev_enumerate *udev_enumerate_new(struct udev *udev); ``` | **参数** | **类型** | **说明** | |----------|----------|----------| | `udev` | `struct udev*` | 由 `udev_new()` 创建的上下文对象 | | **返回值** | `struct udev_enumerate*` | 成功:枚举器对象指针<br>失败:`NULL` | #### ✅ 3. **使用步骤(附代码示例)** ```c #include <libudev.h> int main() { // 创建udev上下文 struct udev *udev_ctx = udev_new(); if (!udev_ctx) return 1; // 创建枚举器对象 ✅ 核心步骤 struct udev_enumerate *enumerate = udev_enumerate_new(udev_ctx); if (!enumerate) { udev_unref(udev_ctx); return 1; } // 设置过滤器(示例:扫描USB设备) udev_enumerate_add_match_subsystem(enumerate, "usb"); // 执行设备扫描 udev_enumerate_scan_devices(enumerate); // 获取设备链表首节点 struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate); // 遍历设备链表 struct udev_list_entry *entry; udev_list_entry_foreach(entry, devices) { const char *syspath = udev_list_entry_get_name(entry); struct udev_device *dev = udev_device_new_from_syspath(udev_ctx, syspath); // 处理设备信息... udev_device_unref(dev); } // 释放资源 udev_enumerate_unref(enumerate); udev_unref(udev_ctx); return 0; } ``` #### ✅ 4. **关键特性** 1. **过滤器机制** 通过组合过滤器精确匹配设备: ```c // 添加子系统过滤(如USB) udev_enumerate_add_match_subsystem(enumerate, "usb"); // 添加属性过滤(如厂商ID) udev_enumerate_add_match_sysattr(enumerate, "idVendor", "0781"); // 添加标签过滤 udev_enumerate_add_match_tag(enumerate, "storage"); ``` 2. **扫描模式** 支持两种扫描方式: ```c udev_enumerate_scan_devices(enumerate); // 扫描物理设备 udev_enumerate_scan_subsystems(enumerate); // 扫描子系统 ``` 3. **设备链表遍历** 扫描结果以链表形式存储: $$ \text{链表结构}:\text{entry}_1 \rightarrow \text{entry}_2 \rightarrow \cdots \rightarrow \text{entry}_n $$ 使用宏高效遍历: ```c udev_list_entry_foreach(entry, devices) { // 处理每个entry } ``` #### ✅ 5. **错误处理** - **创建失败**:通常因内存不足或无效上下文引起 - **扫描失败**:检查返回值(负数表示错误) - **资源泄漏**:必须成对调用 `udev_enumerate_unref()` #### ✅ 6. **典型应用场景** 1. **USB设备监控** 如引用[2]所示,配合 `udev_monitor` 实现实时插拔检测[^2]: ```c // 创建监控对象 struct udev_monitor *mon = udev_monitor_new_from_netlink(udev_ctx, "udev"); udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", NULL); // 与枚举器结合使用 udev_monitor_enable_receiving(mon); ``` 2. **设备属性提取** 获取关键信息: ```c const char *vendor = udev_device_get_sysattr_value(dev, "idVendor"); const char *serial = udev_device_get_property_value(dev, "ID_SERIAL"); ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我变了_我没变

随意 。。。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值