跳轉到內容

Python 程式設計/Dbus

來自華夏公益教科書,自由的教科書


在 Linux 中,Dbus 是一種程序之間通訊的方式。例如,像 Pidgin 這樣的即時通訊程式允許其他程式查詢或更改使用者的狀態(線上、離開等)。另一個例子是 network-manager 服務,它釋出了哪個網際網路連線處於活動狀態。然後,有時連線到網際網路的程式可以選擇最佳時間下載系統更新。

匯流排

[編輯 | 編輯原始碼]

訊息透過匯流排傳送。服務附加到這些總線上,並允許客戶端傳遞訊息到它們或從它們傳遞訊息。

主要有兩個匯流排,系統匯流排會話匯流排。系統總線上的服務會影響整個系統,例如提供有關網路或磁碟驅動器的資訊。會話總線上的服務提供對桌面執行的程式的訪問,例如 Pidgin。

import dbus

sys_bus = dbus.SystemBus()

物件和介面

[編輯 | 編輯原始碼]

附加到匯流排的服務可以使用它們的知名名稱進行聯絡。雖然這可以是任何字串,但格式通常是反向域名格式:來自“My Corp Inc.”的名為“CalcProgram”的電子表格程式的示例可能是“com.mycorp.CalcProgram”。

服務使用斜槓分隔的路徑釋出物件(這類似於網頁)。如果知道此路徑,D-Bus 上的某人可以請求一個物件。

傳回的物件不是完整的物件:它只是引用服務的該物件的副本。它被稱為代理物件

proxy_for_cell_a2 = sys_bus.get_object('com.mycorp.CalcProgram', '/spreadsheet1/cells/a2')

在使用代理物件之前,我們需要指定它的型別。我們透過建立一個介面物件來做到這一點。

cell_a2 = dbus.Interface(proxy_for_cell_a2, 'com.mycorp.CalcProgram.SpreadsheetCell')

可以呼叫為這種型別的物件設定的任何方法

cell_a2.getContents()
名稱 示例 描述
服務的知名名稱 com.mycorp.CalcProgram 標識應用程式
物件的路徑 /spreadsheet1/cells/a2 標識服務釋出的一個物件
介面 com.mycorp.CalcProgram.SpreadsheetCell 標識我們期望的哪種型別的物件

dbus-python 示例

[編輯 | 編輯原始碼]

這些示例已使用 dbus-python 0.83.0 進行測試。較舊的庫版本可能沒有相同的介面。

呼叫介面的方法/列出 HAL 裝置

import dbus

bus = dbus.SystemBus()
hal_manager_object = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
hal_manager_interface = dbus.Interface(hal_manager_object, 'org.freedesktop.Hal.Manager')

# calling method upon interface
print hal_manager_interface.GetAllDevices()

# accessing a method through 'get_dbus_method' through proxy object by specifying interface
method = hal_manager_object.get_dbus_method('GetAllDevices', 'org.freedesktop.Hal.Manager')
print(method())

# calling method upon proxy object by specifying the interface to use
print( hal_manager_object.GetAllDevices(dbus_interface='org.freedesktop.Hal.Manager'))

內省一個物件

import dbus

bus = dbus.SystemBus()
hal_manager_object = bus.get_object(
    'org.freedesktop.Hal',          # service
    '/org/freedesktop/Hal/Manager'  # published object
)

introspection_interface = dbus.Interface(
    hal_manager_object,
    dbus.INTROSPECTABLE_IFACE,
)

# Introspectable interfaces define a property 'Introspect' that
# will return an XML string that describes the object's interface
interface = introspection_interface.Introspect()
print(interface)

Avahi

import dbus

sys_bus = dbus.SystemBus()

# get an object called / in org.freedesktop.Avahi to talk to
raw_server = sys_bus.get_object('org.freedesktop.Avahi', '/')

# objects support interfaces. get the org.freedesktop.Avahi.Server interface to our org.freedesktop.Avahi object.
server = dbus.Interface(raw_server, 'org.freedesktop.Avahi.Server')

# The so-called documentation is at /usr/share/avahi/introspection/Server.introspect
print(server)
print(server.GetVersionString())
print(server.GetHostName())

pydbus 示例

[編輯 | 編輯原始碼]

這些示例已使用 pydbus 0.2 和 0.3 進行測試。

呼叫介面的方法/列出 systemd 單位

from pydbus import SystemBus

bus = SystemBus()
systemd = bus.get(
    '.systemd1' # service name - names starting with . automatically get org.freedesktop prepended.
    # no object path - it'll be set to the service name transformed to the path format (/org/freedesktop/systemd1)
)

for unit in systemd.ListUnits()[0]:
    print(unit)

內省一個物件

from pydbus import SystemBus

bus = SystemBus()
systemd = bus.get('.systemd1')

# Introspectable interfaces define a property 'Introspect' that
# will return an XML string that describes the object's interface
print(systemd.Introspect()[0])

# Introspection data is automatically converted to Python's help system data
help(systemd)

Avahi

from pydbus import SystemBus

bus = SystemBus()

# get an object called / in org.freedesktop.Avahi to talk to
avahi = bus.get('.Avahi', '/')

# See the object's API
help(avahi)

print(avahi.GetVersionString())
print(avahi.GetHostName())

參考文獻

[編輯 | 編輯原始碼]
華夏公益教科書