这段Python代码发生了什么?

2 投票
2 回答
589 浏览
提问于 2025-04-17 20:24

下面这段代码来自于一个pyusb 教程,它的目的是用来找到所有连接的打印机:

import usb.core
import usb.util
import sys

class find_class(object):
    def __init__(self, class_):
        self._class = class_
    def __call__(self, device):
        # first, let's check the device
        if device.bDeviceClass == self._class:
            return True
        # ok, transverse all devices to find an
        # interface that matches our class
        for cfg in device:
            # find_descriptor: what's it?
            intf = usb.util.find_descriptor(
                                    cfg,
                                    bInterfaceClass=self._class
                                )
            if intf is not None:
                return True

        return False

printers = usb.core.find(find_all=1, custom_match=find_all(7))

这个类似乎有很多地方返回布尔值(也就是真或假)。那么总共有多少个返回值呢?

另外,我不太明白这段代码是怎么搜索系统中所有连接的打印机的。以下几点让我困惑:

  • device是一个列表还是元组?如果是的话,这段代码是怎么只执行一次if device.bDeviceClass == self._class:就能检查所有设备的?

  • 这一行self._class = class_在干什么?

  • 为什么在printers = usb.core.find(find_all=1, custom_match=find_all(7))中,类find_class从来没有被实例化?

    如果你有使用过pyusb或任何USB程序的经验,请告诉我你的看法。

2 个回答

1

为什么在这行代码中 find_class 从来没有被实例化:printers = usb.core.find(find_all=1, custom_match=find_all(7))

在你提到的教程中,这其实是个笔误。接下来那行代码正确地使用了 custom_match=find_class(7)

这一行代码 self._class = class_ 是在做什么?

在这个例子中,它把 self._class 设置为 7。(这个值来自 find_class(7) 这一行。)不使用 self.class = class 的原因是“class”是一个保留字,会导致语法错误。也许这样写会更好:

class find_class(object):
    def __init__(self, class_nr):
        self.class_nr = class_nr

我也不明白这段代码是如何搜索系统中所有连接的打印机的。

正如教程中提到的,usb.core.find() 默认只返回找到的第一个设备,除非你给 find_all 参数传入一个真值。并不是你看到的代码在搜索所有设备,而是 usb.core.find() 在做这件事。这个也回答了下一个问题:

device 是列表/元组吗?

不是。

这个类似乎有多个地方返回布尔值。总共有多少个返回值?

__call__() 会为每个 usb.core.find() 找到的设备被调用。设备信息会传入 device__call__() 每次调用只会返回一次(显然)。它被调用的次数取决于系统中找到的设备数量。

你在里面看到的循环只针对单个设备!在这个情况下,如果设备是 7 类,或者它的任何配置有一个 7 类的接口,自定义搜索就会成功。

1

设备是一个列表/元组吗?

device 是一个 usb.core.Device。遍历它会 得到配置

如果是的话,代码是怎么通过执行 if device.bDeviceClass == self._class: 只检查一次所有设备的?

其实并不是。你错过了那部分内容,它说“所以,要真正找到连接到系统的所有打印机,我们需要遍历所有配置,然后遍历所有接口,检查其中一个接口的 bInterfaceClass 字段是否等于 7。”

这一行 self._class = class 是在做什么?

就是字面意思。它把那个参数中的对象绑定到这个属性上,以便后面使用。

为什么在 printers = usb.core.find(find_all=1, custom_match=find_all(7)) 中从未实例化过类 find_class?

因为有人想错了。最后那部分应该是 ...=find_class(7)

撰写回答