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
.
中实现
希望对您有所帮助。
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
.
希望对您有所帮助。