Python编程
Completion requirements
在 Linux 中,Dbus 是一种进程间通信的方式。例如,像 Pidgin 即时通讯程序这样的应用程序允许其他程序查询或更改用户的状态(如可用、离开等)。另一个例子是网络管理器服务,它发布了当前活跃的互联网连接。那些偶尔连接到互联网的程序可以在最佳时机下载系统更新。
总线
消息沿着总线发送。服务将自己附加到这些总线上,并允许客户端向它们发送和接收消息。
主要有两种总线,系统总线和会话总线。系统总线上的服务影响整个系统,例如提供关于网络或磁盘驱动器的信息。会话总线上的服务提供对桌面上运行的程序的访问,例如 Pidgin。
import dbus
sys_bus = dbus.SystemBus()
对象和接口
附加到总线上的服务可以通过它们的知名名称进行联系。虽然这个名称可以是任何字符串,但通常格式是反向域名:例如,名为“CalcProgram”的电子表格程序,来自“My Corp Inc.”,其名称可以是“com.mycorp.CalcProgram”。
服务通过斜杠分隔的路径来发布对象(这类似于网页)。如果某人在 Dbus 上知道这个路径,他们可以请求这个对象。
返回的对象不是完整的对象:它仅仅是指向服务的对象副本。它被称为代理对象。
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()
名称 | 示例 | 描述 |
---|---|---|
service well known name | com.mycorp.CalcProgram | 标识应用程序 |
path of an object | /spreadsheet1/cells/a2 | 标识由服务发布的对象 |
interface | 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')
# 调用接口的方法
print(hal_manager_interface.GetAllDevices())
# 通过代理对象访问方法,指定接口
method = hal_manager_object.get_dbus_method('GetAllDevices', 'org.freedesktop.Hal.Manager')
print(method())
# 通过代理对象调用方法,指定要使用的接口
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', # 服务
'/org/freedesktop/Hal/Manager' # 发布的对象
)
introspection_interface = dbus.Interface(
hal_manager_object,
dbus.INTROSPECTABLE_IFACE,
)
# 可 introspectable 接口定义了一个属性 'Introspect',
# 它将返回一个描述对象接口的 XML 字符串
interface = introspection_interface.Introspect()
print(interface)
Avahi:
import dbus
sys_bus = dbus.SystemBus()
# 获取与 org.freedesktop.Avahi 对话的对象
raw_server = sys_bus.get_object('org.freedesktop.Avahi', '/')
# 对象支持接口。获取我们的 org.freedesktop.Avahi 对象的 org.freedesktop.Avahi.Server 接口。
server = dbus.Interface(raw_server, 'org.freedesktop.Avahi.Server')
# 所谓的文档位于 /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' # 服务名称 - 以 . 开头的名称会自动加上 org.freedesktop 前缀
# 没有对象路径 - 它将设置为服务名称并转换为路径格式(/org/freedesktop/systemd1)
)
for unit in systemd.ListUnits()[0]:
print(unit)
检查对象:
from pydbus import SystemBus
bus = SystemBus()
systemd = bus.get('.systemd1')
# 可 introspectable 接口定义了一个属性 'Introspect',
# 它将返回一个描述对象接口的 XML 字符串
print(systemd.Introspect()[0])
# introspection 数据会自动转换为 Python 的帮助系统数据
help(systemd)
Avahi:
from pydbus import SystemBus
bus = SystemBus()
# 获取与 org.freedesktop.Avahi 对话的对象
avahi = bus.get('.Avahi', '/')
# 查看对象的 API
help(avahi)
print(avahi.GetVersionString())
print(avahi.GetHostName())
Last modified: Friday, 31 January 2025, 1:49 AM