的Python d总线:带有装饰
TL定制d总线方法名;博士的Python d总线:带有装饰
是否有具有用于导出d总线的方法的自定义名称是从该方法的名称被装饰不同的任何方式?
所以这里的交易:我想有一个注册上的单个对象d总线具有多个接口,所有的接口有相同的方法(不同的实现):
/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
作为最后的手段,但我希望有一个更好的解决方案呢。
TL;博士
不,我不相信它可以与DBUS的Python这样做,但是下面是一个变通:
如果要求是有一个单独的类,这将是有问题的,因为Python本身不支持方法重载,所以在同一个类中不能有多个具有完全相同名称的方法。我假设用例是在不同的接口下共享在D-Bus上导出的多个方法之间的方法的实现?如果是这样,有一个解决方案。
我相信你正在使用的Dbus总线绑定(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和在service.py
周围看看在_method_lookup
方法。 method
修饰器在decorators.py
中实施。
希望这会有所帮助。
这与我正在使用的解决方法类似,唯一的区别是我没有类似'Implementation'的内容。我只是(和你的情况一样)将这些类链接在一起,以便python的MRO为我找到合适的类。我想出的另一个解决方案是覆盖'_method_lookup'并将我自己的属性添加到每个处理程序。 –
好的,很酷。我想,如果你想出了同样的解决方案,我的“答案”对人们来说可能是可以接受和有用的。如果您认为合适,请接受它。干杯! – JoGr
它肯定会帮助其他人。但我可能想等待其他答案。这个解决方案相当有用: -/ –