的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中实施。

希望这会有所帮助。

+0

这与我正在使用的解决方法类似,唯一的区别是我没有类似'Implementation'的内容。我只是(和你的情况一样)将这些类链接在一起,以便python的MRO为我找到合适的类。我想出的另一个解决方案是覆盖'_method_lookup'并将我自己的属性添加到每个处理程序。 –

+0

好的,很酷。我想,如果你想出了同样的解决方案,我的“答案”对人们来说可能是可以接受和有用的。如果您认为合适,请接受它。干杯! – JoGr

+0

它肯定会帮助其他人。但我可能想等待其他答案。这个解决方案相当有用: -/ –