我正在编写一个小程序来列出可用的USB设备。我创建了一个带有函数的分隔文件,以便可以随时从其他脚本访问它。此函数的主要目的是返回列表/数组作为输出。如果我使用print命令,它会成功打印可用设备列表。但是,当我使用return命令时,它只会重新调用第一个检测到的设备。我从SO那里经历了其他类似的问题但是找不到任何有效的解决方案。这是我尝试使用dbus的代码。任何帮助都是适当的。
#!/usr/bin/python2.7
import dbus
def find_usb(self):
bus = dbus.SystemBus()
ud_manager_obj = bus.get_object("org.freedesktop.UDisks", "/org/freedesktop/UDisks")
ud_manager = dbus.Interface(ud_manager_obj, 'org.freedesktop.UDisks')
for dev in ud_manager.EnumerateDevices():
device_obj = bus.get_object("org.freedesktop.UDisks", dev)
device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE)
if device_props.Get('org.freedesktop.UDisks.Device', "DriveConnectionInterface") == "usb" and device_props.Get('org.freedesktop.UDisks.Device', "DeviceIsPartition"):
if device_props.Get('org.freedesktop.UDisks.Device', "DeviceIsMounted"):
device_file = device_props.Get('org.freedesktop.UDisks.Device', "DeviceFile")
#print device_file
return device_file
else:
print "Device not mounted"
find_usb("")
答案 0 :(得分:4)
您将返回匹配的第一个设备。建立一个列表并返回该列表:
def find_usb(self):
bus = dbus.SystemBus()
ud_manager_obj = bus.get_object("org.freedesktop.UDisks", "/org/freedesktop/UDisks")
ud_manager = dbus.Interface(ud_manager_obj, 'org.freedesktop.UDisks')
found = []
for dev in ud_manager.EnumerateDevices():
device_obj = bus.get_object("org.freedesktop.UDisks", dev)
device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE)
if device_props.Get('org.freedesktop.UDisks.Device', "DriveConnectionInterface") == "usb" and device_props.Get('org.freedesktop.UDisks.Device', "DeviceIsPartition"):
if device_props.Get('org.freedesktop.UDisks.Device', "DeviceIsMounted"):
device_file = device_props.Get('org.freedesktop.UDisks.Device', "DeviceFile")
#print device_file
found.append(device_file)
else:
print "Device not mounted"
return found
return
语句立即结束该功能;通过在循环中放置return
,您可以在该点退出函数并过早地结束循环。
另一种方法是使用yield
statement生成匹配项,使其成为生成器函数;然后,您可以仅将self.find_usb()
的结果循环一遍,但您将按需生成设备文件:
def find_usb(self):
bus = dbus.SystemBus()
ud_manager_obj = bus.get_object("org.freedesktop.UDisks", "/org/freedesktop/UDisks")
ud_manager = dbus.Interface(ud_manager_obj, 'org.freedesktop.UDisks')
for dev in ud_manager.EnumerateDevices():
device_obj = bus.get_object("org.freedesktop.UDisks", dev)
device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE)
if device_props.Get('org.freedesktop.UDisks.Device', "DriveConnectionInterface") == "usb" and device_props.Get('org.freedesktop.UDisks.Device', "DeviceIsPartition"):
if device_props.Get('org.freedesktop.UDisks.Device', "DeviceIsMounted"):
device_file = device_props.Get('org.freedesktop.UDisks.Device', "DeviceFile")
#print device_file
yield device_file
else:
print "Device not mounted"
return found
然而,生成器是一种更先进的技术。
答案 1 :(得分:1)
您应该创建一个列表变量并将设备附加到它。然后在函数的末尾,返回列表。
#!/usr/bin/python2.7
import dbus
def find_usb(self):
devices = [] # instantiate empty list variable!
bus = dbus.SystemBus()
ud_manager_obj = bus.get_object("org.freedesktop.UDisks", "/org/freedesktop/UDisks")
ud_manager = dbus.Interface(ud_manager_obj, 'org.freedesktop.UDisks')
for dev in ud_manager.EnumerateDevices():
device_obj = bus.get_object("org.freedesktop.UDisks", dev)
device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE)
if device_props.Get('org.freedesktop.UDisks.Device', "DriveConnectionInterface") == "usb" and device_props.Get('org.freedesktop.UDisks.Device', "DeviceIsPartition"):
if device_props.Get('org.freedesktop.UDisks.Device', "DeviceIsMounted"):
device_file = device_props.Get('org.freedesktop.UDisks.Device', "DeviceFile")
#print device_file
devices.append(device_file)
else:
print "Device not mounted"
return devices
find_usb("")
答案 2 :(得分:0)
甚至理解你的代码的一个大问题是逻辑结构隐藏在很多缩进中。这是一个重写,保留原始操作,同时允许看到结构。
#!/usr/bin/python2.7
import dbus
def find_usb(self):
ofud = 'org.freedesktop.UDisks' # convenience string for brevity
bus = dbus.SystemBus()
ud_manager_obj = bus.get_object(ofud, "/org/freedesktop/UDisks")
ud_manager = dbus.Interface(ud_manager_obj, ofud)
for dev in ud_manager.EnumerateDevices():
device_obj = bus.get_object(ofud, dev)
device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE)
dp_get = device.props.Get # convenience method for brevity
if (dp_get(ofud, "DriveConnectionInterface") == "usb" and
dp_get(ofud, "DeviceIsPartition")):
if dp_get(ofud, "DeviceIsMounted"):
device_file = dp_get(ofud + '.Device', "DeviceFile")
print device_file
return device_file
else:
print "Device not mounted"
return None # implied
else:
return None # implied
return None
find_usb("")
其他人已经充分回答了问题所在,但阅读困难并没有帮助。部分原因不是你的错,dbus接口很冗长,但有些东西可以像我对ofud
和dp_get
那样驯服。
PEP-8 Style Guide for Python和PEP-20 The Zen of Python在很大程度上存在,可帮助您编写使错误更易于查看的代码。特别是,你的条件的深层嵌套可以清理很多:
if dp_get(ofud, 'DriveConnectionInterface') != 'usb':
continue
if dp_get(ofud, 'DeviceIsPartition') and dp_get(oufd, 'DeviceIsMounted'):
device_file = dp_get(oufd + '.Device', "DeviceFile")
found.append(device_file)
由于您的原始代码对非usb设备没有任何作用,因此更快地“快速失败”到循环的下一次迭代并跳过整个缩进级别。肯定有其他方法可以使代码的意图更加明显,我刚刚展示了一些。
可读性至关重要。