簡體   English   中英

dbus-python 如何獲得原生類型的響應?

[英]dbus-python how to get response with native types?

我正在使用 dbus-python,我需要將響應(fe dbus.Dictionary - 但通常是任何響應)作為本機 Python 類型。 是的,可以編寫遞歸轉換器,但我想我一定遺漏了一些明顯的東西? 必須有一種方法可以使用 dbus 將這些怪物轉換回 Python 原生類型。 或者不是?

dbus.Dictionary({dbus.String(u'CanGoNext'): dbus.Boolean(True, variant_level=1), dbus.String(u'CanPause'): dbus.String(u'MinimumRate'): dbus.Int32(14, variant_level=1) ...

雖然 Martin 是對的,但它不適用於由 python 轉換為 int 的布爾值(因為 bool 不能被子類化)。

In [3]: print(dbus.Boolean(False))
0

不幸的是,遞歸轉換器是保留布爾值的唯一方法。

這是一個示例實現:

import dbus


def python_to_dbus(data):
    '''
        convert python data types to dbus data types
    '''
    if isinstance(data, str):
        data = dbus.String(data)
    elif isinstance(data, bool):
        # python bools are also ints, order is important !
        data = dbus.Boolean(data)
    elif isinstance(data, int):
        data = dbus.Int64(data)
    elif isinstance(data, float):
        data = dbus.Double(data)
    elif isinstance(data, list):
        data = dbus.Array([python_to_dbus(value) for value in data], signature='v')
    elif isinstance(data, dict):
        data = dbus.Dictionary(data, signature='sv')
        for key in data.keys():
            data[key] = python_to_dbus(data[key])
    return data


def dbus_to_python(data):
    '''
        convert dbus data types to python native data types
    '''
    if isinstance(data, dbus.String):
        data = str(data)
    elif isinstance(data, dbus.Boolean):
        data = bool(data)
    elif isinstance(data, dbus.Int64):
        data = int(data)
    elif isinstance(data, dbus.Double):
        data = float(data)
    elif isinstance(data, dbus.Array):
        data = [dbus_to_python(value) for value in data]
    elif isinstance(data, dbus.Dictionary):
        new_data = dict()
        for key in data.keys():
            new_data[key] = dbus_to_python(data[key])
        data = new_data
    return data

為了使它更容易在處理 dbus 源數據的類中使用,您可以使用裝飾器:

def convert_to_python(func):
    def wrapper(*args, **kwargs):
        return dbus_to_python(func(*args, **kwargs))
    return wrapper
...

@convert_to_python
def dbus_method_call(self):
    return self.dbus_proxy.Method()

這樣,上面 dbus_method_call 返回的任何數據都將轉換為原生 python。

請參閱此相關問題: dbus Variant: How to preserve boolean datatype in Python?

你不需要。 它們是本機類型的子類,因此您只需像使用本機類型一樣使用它們:

>>> import dbus
>>> v = dbus.Dictionary({dbus.String(u'CanGoNext'): dbus.Boolean(True, variant_level=1), dbus.String(u'CanPause'): dbus.Boolean(False, variant_level=1), dbus.String(u'MinimumRate'): dbus.Int32(14, variant_level=1)})
>>> print v['MinimumRate']
14
>>> if v['CanGoNext']: print 'Go'
... 
Go
>>> if v['CanPause']: print 'Pause'
... 
>>> 

正如@Martin Vidner 所說,在您的代碼中,您無需執行任何操作即可使用它們。

為了漂亮的打印,您可以使用現有的“遞歸轉換器”,例如json

import json
print(json.dumps(d, indent=2))

輸出

{
  "MinimumRate": 14, 
  "CanGoNext": 1, 
  "CanPause": 0
}

它丟失了有關類型的信息。

上面 florent-thiery 的代碼對於從 dbus 類型轉換為 python 本機類型非常有用,反之亦然。 但是,它需要對dbus_to_python進行一些小的更改,如下所示:

    elif isinstance(data, dbus.Dictionary):
        new_data = dict()
        for key in data.keys():
            # key below is a dbus type and needs coversion
            # before using it in the dict as key
            pkey = dbus_to_python(key)
            new_data[pkey] = dbus_to_python(data[key])
        data = new_data

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM