D-bus信号中的嵌套字典

时间:2015-07-27 16:26:59

标签: python dbus

有课

class MyService(dbus.service.Object):
  def __init__(self):
    bus_name = dbus.service.BusName(__dbus_object_name__, bus=dbus.SessionBus())
    dbus.service.Object.__init__(self, bus_name, __dbus_object_path__)

  @dbus.service.signal(__dbus_object_name__, signature='a{sv}')
  def TickSignal(self, info):
    print(info)
s = MyService()

尝试发送嵌套字典

s.TickSignal({' a':'''':1,' c':{&#39 ;'' a'}})工作正常,但如果嵌套的dict包含数字导致异常

s.TickSignal({' a':' b',' b':1,' c':{&#39 ;':' a',' b':1}})

Traceback (most recent call last):
  File "sig.py", line 26, in <module>
    s.TickSignal({'a': 'b', 'b': 1, 'c':{'a':'a', 'b':1}})
  File "/usr/lib/python3/dist-packages/dbus/decorators.py", line 314, in emit_signal
    message.append(signature=signature, *args)
TypeError: Expected a string or unicode object

2 个答案:

答案 0 :(得分:0)

如果没有明确指定签名,您正在使用的D-Bus绑定(dbus-python)将假定词典中的所有类型都与字典中的任意项相同。在这种情况下,dbus-python假设字典中的所有项都是'ss'。

来自dbus-python tutorial

  

字典由Python字典表示,或由dict.Dictionary表示,它是dict的子类。发送字典时,如果有可用的内省签名,则会使用该字典;否则,如果将signature关键字参数传递给Dictionary构造函数,那么将用于确定内容的键和值签名;否则,dbus-python将从dict的任意项猜测。

因此,您需要指明字典中的类型。显式指定签名的一种方法是创建如下数据:

inner = dbus.Dictionary({'a': 'a', 'b': 1}, signature='sv')
outer = dbus.Dictionary({'a': 'b', 'b': 1, 'c': inner}, signature='sv')
s.TickSignal(outer)

希望这有帮助。

答案 1 :(得分:0)

您可以使用这样的嵌套字典:

self._properties = dbus.Dictionary({
            'Metadata': dbus.Dictionary({
                'mpris:length': dbus.Int64(2400000000),
                'mpris:artUrl': 'file:///home/user/1.jpg',
                'xesam:artist': ['1', '2'],
                'xesam:title': 'hello world',
                'xesam:url': '',
                'xesam:album': 'hehe'
            }, signature='sv'),
            'CanControl': True
        }, signature='sv')

它应该有用。