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

Python D-Bus: custom d-bus method name with decorator

tl;dr

是否有任何方法可以为导出的 d-bus 方法自定义名称,使其与被修饰的方法名称不同?


事情是这样的:我想在具有多个接口的 D-Bus 上注册一个对象,其中所有接口都具有相同的方法(不同的实现):

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

如果我要使用 class 表示单个对象并使用 method decorator 将 class 的方法导出到 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 实际上将 class 方法名称与 D-Bus 方法名称进行一对一映射,并且由于 class 不能包含两个具有相同名称的方法,这似乎是不可能的。我正在考虑将覆盖 _method_lookup 作为最后的手段,但我希望有更好的解决方案。

tl;dr

不,我不相信可以使用 dbus-python 以这种方式完成,但下面是一个解决方法:


如果要求只有一个 class 这将是有问题的,因为 Python 本身不支持方法重载,因此在相同 class。我假设用例是在不同接口下在 D-Bus 上导出的多个方法之间共享方法的实现?如果是,有解决办法。

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

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

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

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 并查看 service.py 中的 _method_lookup 方法。 method 装饰器在 decorators.py.

中实现

希望对您有所帮助。