Pyudev:即使属性存在,也会引发 KeyError

Posted

技术标签:

【中文标题】Pyudev:即使属性存在,也会引发 KeyError【英文标题】:Pyudev : KeyError raised even though property exists 【发布时间】:2014-04-30 12:35:36 【问题描述】:

我正在尝试在 python 中使用 pyudev 监控和过滤 USB 大容量存储设备。在给定的代码中,如果设备的ID_FS_USAGE 属性为None,则会被过滤掉:

import gtk
from pyudev import Context,Monitor
from pyudev.glib import GUDevMonitorObserver

dev_label = ["0","0"]
serial_list = []
context = Context()
monitor = Monitor.from_netlink(context)
monitor.filter_by(subsystem='block')
observer = GUDevMonitorObserver(monitor)

print dev_label


def device_connected(observer, device):

    flag_device = False
    flag_serial = False

    print device['DEVNAME']
    if device['ID_FS_USAGE'] == None : #HERE IS WHERE THE TROUBLE IS
        flag_device = True

    for iden in serial_list:
        if iden == device.__getitem__('ID_SERIAL_SHORT'):
            flag_serial =True

    if flag_device == False and flag_serial == False:

        print dev_label
        serial_list.append(device.__getitem__('ID_SERIAL_SHORT'))
        Welcome.device_count+=1

        if device.__getitem__('ID_FS_LABEL')is not None:
            dev_label[Welcome.device_count-1]=str(device.__getitem__('ID_FS_LABEL'))
            label = gtk.Label('Device connected :: 0!r'.format(dev_label[Welcome.device_count-1]))
        else :

            dev_label[Welcome.device_count-1]=str(device.__getitem__('ID_FS_UUID'))
            label = gtk.Label('Device connected :: 0!r'.format(dev_label[Welcome.device_count-1]))
        Welcome.vbox.pack_start(label)
        Welcome.window.show_all()



        if Welcome.device_count<2:
            label = gtk.Label('Connect the second device')
            Welcome.vbox.pack_start(label)
            Welcome.window.show_all()


        else :
            Exchange()

observer.connect("device-added",device_connected)
monitor.start()

class Welcome:
    device_count = 0    
    window = gtk.Window()
    vbox= gtk.VBox(False, 5)


    def __init__(self):

        self.window.set_default_size(300, 300)
        self.window.set_title("Welcome")

        label = gtk.Label("Connect the desired device")

        self.vbox.pack_start(label)
        self.window.add(self.vbox)

        self.window.connect("destroy", lambda q: gtk.main_quit())
        self.window.show_all()

class Exchange:

    window1 = gtk.Window()
    window1.set_title(dev_label[0])
    window2 = gtk.Window()
    window2.set_title(dev_label[1])
    def __init__(self):

        width = gtk.gdk.screen_get_default().get_width()
        height = gtk.gdk.screen_get_default().get_height()

        self.window1.resize(width/2,height)
        self.window2.resize(width/2,height)

        self.window2.move(self.window1.get_position()[0]+width/2, self.window1.get_position()[1])

        label = gtk.Label("Hello")
        self.window1.add(label)

        self.window1.connect("destroy" , lambda q : gtk.main_quit())
        self.window1.show_all()

        label = gtk.Label("World")
        self.window2.add(label)

        self.window2.connect("destroy",lambda q : gtk.main_quit())
        self.window2.show_all()        

observer.connect("device-added",device_connected)
monitor.start()


Welcome()
gtk.main()

执行上述代码后显示的回溯是:

['0', '0']
/dev/sdc
Traceback (most recent call last):
  File "project.py", line 27, in device_connected
    if device['ID_FS_USAGE'] == None :
  File "/usr/lib/python2.7/dist-packages/pyudev/device.py", line 831, in __getitem__
    raise KeyError(property)
KeyError: 'ID_FS_USAGE'
/dev/sdc
Traceback (most recent call last):
  File "project.py", line 27, in device_connected
    if device['ID_FS_USAGE'] == None :
  File "/usr/lib/python2.7/dist-packages/pyudev/device.py", line 831, in __getitem__
    raise KeyError(property)
KeyError: 'ID_FS_USAGE'
/dev/sdc1
['0', '0']
/dev/sdc1
/dev/sde
Traceback (most recent call last):
  File "project.py", line 27, in device_connected
    if device['ID_FS_USAGE'] == None :
  File "/usr/lib/python2.7/dist-packages/pyudev/device.py", line 831, in __getitem__
    raise KeyError(property)
KeyError: 'ID_FS_USAGE'
/dev/sde
Traceback (most recent call last):
  File "project.py", line 27, in device_connected
    if device['ID_FS_USAGE'] == None :
  File "/usr/lib/python2.7/dist-packages/pyudev/device.py", line 831, in __getitem__
    raise KeyError(property)
KeyError: 'ID_FS_USAGE'
/dev/sdd
Traceback (most recent call last):
  File "project.py", line 27, in device_connected
    if device['ID_FS_USAGE'] == None :
  File "/usr/lib/python2.7/dist-packages/pyudev/device.py", line 831, in __getitem__
    raise KeyError(property)
KeyError: 'ID_FS_USAGE'
/dev/sdd
Traceback (most recent call last):
  File "project.py", line 27, in device_connected
    if device['ID_FS_USAGE'] == None :
  File "/usr/lib/python2.7/dist-packages/pyudev/device.py", line 831, in __getitem__
    raise KeyError(property)
KeyError: 'ID_FS_USAGE'

我连接了两个设备,一个 USB 存储驱动器和一个处于 USB 大容量存储模式的智能手机。对应于 USB 内存驱动器的 /dev 条目是 /dev/sdc/dev/sdc1/dev/sdd/dev/sde 对应手机。这里设备/dev/sdd 确实有一个名为ID_FS_USAGE 的属性,它不是没有。但它仍然会引发 KeyError 。令人惊讶的是,/dev/sdc1 没有出现此类错误。出了什么问题?请帮忙!

【问题讨论】:

【参考方案1】:

您只收到第一个设备错误的原因可能是python在第一个错误时停止。

如果不使用 device['ID_FS_USAGE'] 而不是在没有属性匹配的情况下失败,您需要使用 device.get('ID_FS_USAGE') 它将返回 None 以获取缺少的属性。

【讨论】:

Python 不会停止执行。它完美地执行/dev/sdc1(按预期执行窗口)。问题在于读取手机的ID_FS_USAGE 属性(/dev/sdd 应该像/dev/sdc1 一样执行,但它没有) .get() 确实删除了上一个错误中的错误,尽管它也没有读取ID_FS_USAGE 的值。 尝试使用print dir(device) 打印每个设备的属性列表,可能它没有被安装为块设备。 我能问一下您为什么使用__get_item__ 而不是get 它是a)私人成员,b)要输入更多内容并且c)看起来更糟? 这里是 print dir(device) 的粘贴箱:pastebin.com/rbbSyFKB。好吧,我是 pyudev 的新手,并阅读了一些他们使用 __getitem__ 的教程/示例。我明白你的观点,也喜欢它。会改的

以上是关于Pyudev:即使属性存在,也会引发 KeyError的主要内容,如果未能解决你的问题,请参考以下文章

即使代码具有给定值,ValueError 也会引发

即使引发 SQLException,flywaydb 也会应用 java 迁移

即使设置了 serialVersionUID,反序列化也会引发 InvalidClassException

即使内容和代码最少,扩展 viewcell 的自定义控件也会引发 System.InvalidCastException

即使@Autowire和@ repository @ service已正确配置,也会引发NoSuchBeanDefinitionException

即使所有标签都是唯一的,YOLOv5 也会引发重复标签错误