2015-09-24 74 views
0

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作爲最後的手段,但我希望有一個更好的解決方案呢。

回答

0

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

它肯定會幫助其他人。但我可能想等待其他答案。這個解決方案相當有用: -/ –