跳转到内容

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())

参考文献

[编辑 | 编辑源代码]
华夏公益教科书