Python D-Bus:带有装饰器的自定义d-bus方法名称

时间:2015-09-24 16:31:01

标签: python dbus

TL;博士

是否有任何方法可以为导出的d-bus方法设置一个自定义名称,该方法与正在修饰的方法名称不同?

所以这是交易:我希望在D-Bus上有一个具有多个接口的单个​​对象,其中所有接口都具有相同的方法(不同的实现):

/com/quaintous
|- com.quaintous.iface1
|  |- GET
|- com.quaintous.iface2
|  |- GET

如果我要使用表示该单个对象的类并使用method decorator将该类的方法导出到d-bus,我就不能有两个同名的方法(第二个会覆盖第一个)。

示例代码(所需)

class Quaintous_DBus(dbus.service.Object):
    def __init__(self):
        bus_name = dbus.service.BusName('com.quaintous', bus=dbus.SessionBus())
        dbus.service.Object.__init__(self, bus_name, '/com/quaintous')


    @dbus.service.method('com.quaintous.iface1', name="GET")
    def get_iface1(self, args):
        # Impl

    @dbus.service.method('com.quaintous.iface2', name="GET")
    def get_iface1(self, args):
        # Impl

类似于name="GET"

更新

python-debus实际上是将类方法名称与D-Bus方法名称进行一对一映射,并且由于类不能包含两个具有相同名称的方法,因此似乎无法做到这一点。我在考虑覆盖_method_lookup作为最后的手段,但我希望有更好的解决方案。

1 个答案:

答案 0 :(得分:0)

<强> TL;博士

不,我不相信可以用dbus-python这样做,但下面是一个解决方法:

如果要求有一个单独的类,这将是有问题的,因为Python本身不支持方法重载,因此在同一个类中不能有多个具有完全相同名称的方法。我假设用例是在不同接口下在D-Bus上导出的多个方法之间共享方法的实现?如果是这样,那就有一个解决方案。

我相信你正在使用的D-Bus绑定(dbus-python)将根据服务上调用的方法名称按名称查找方法,并将其与接口字符串匹配(如果存在这样的字符串)

使用方法名称作为服务类的类层次结构中的类中的__dict__字典中的键来完成方法查找。我相信,这意味着没有简单的方法可以让dbus-python在不改变dbus-python本身的情况下寻找另一种方法。但是,这意味着只需要在层次结构中的某个位置使用具有正确名称的方法,该方法使用特定的接口字符串进行修饰。

如果您创建一个继承层次结构,其中所有方法都出现在一个单独的类中(每个方法具有不同的接口字符串)并共享实现实际逻辑的父级,它似乎以您希望的方式出现在总线上。以下是一个例子:

import gobject
import dbus
import dbus.service

from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)


OPATH = "/temp/Test"
IFACE = "temp.Test"
BUS_NAME = "temp.Test"


class Implementation(object):
    # This is the implementation shared by the methods exported on the bus
    def theX(self, arg):
        print arg


class MyService(dbus.service.Object):
    def __init__(self):
        bus = dbus.SessionBus()
        bus.request_name(BUS_NAME, dbus.bus.NAME_FLAG_REPLACE_EXISTING)
        bus_name = dbus.service.BusName(BUS_NAME, bus=bus)
        dbus.service.Object.__init__(self, bus_name, OPATH)


class IfaceOne(MyService, Implementation):
    def __init__(self):
        MyService.__init__(self)

    @dbus.service.method(dbus_interface=IFACE + ".IfaceOne", in_signature='s')
    def X(self, arg):
        super(IfaceOne, self).theX(arg)


class IfaceTwo(IfaceOne, Implementation):
    def __init__(self):
        MyService.__init__(self)

    @dbus.service.method(dbus_interface=IFACE + ".IfaceTwo", in_signature='s')
    def X(self, arg):
        super(IfaceTwo, self).theX(arg)


if __name__ == "__main__":
    iface_two = IfaceTwo()
    loop = gobject.MainLoop()
    loop.run()

有关详细信息,您可以克隆dbus-python git并浏览_method_lookup中的service.py方法。 method装饰器在decorators.py

中实现

希望这有帮助。