Python - 从函数返回列表/数组

时间:2013-09-11 17:29:27

标签: python function return

我正在编写一个小程序来列出可用的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("")

3 个答案:

答案 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接口很冗长,但有些东西可以像我对ofuddp_get那样驯服。

PEP-8 Style Guide for PythonPEP-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设备没有任何作用,因此更快地“快速失败”到循环的下一次迭代并跳过整个缩进级别。肯定有其他方法可以使代码的意图更加明显,我刚刚展示了一些。

可读性至关重要。