You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python类如何以不同名称初始化?WMI库源码实现困惑

Python WMI库使用与源码实现疑惑解析

找到合适的WMI库

昨天我在Python项目里需要用到WMI,找了一圈发现了对应的Python库,这个库的文档做得相当完善,还有一大堆实用的示例,比如获取本地进程信息:

import wmi
c = wmi.WMI ()
for process in c.Win32_Process ():
    print process.ProcessId, process.Name

或者连接远程机器:

import wmi
c = wmi.WMI ("some_other_machine")

查看源码时的疑惑

我好奇WMI类初始化时能传入哪些参数,于是去翻了源码。原本以为会直接看到类似class WMI:或者def WMI()的定义,结果实际看到的是一个名为_wmi_namespace的类:

# # class WMI #
class _wmi_namespace:
    """A WMI root of a computer system. The classes attribute holds a list of the classes on offer.
    This means you can explore a bit with things like this::
        c = wmi.WMI ()
        for i in c.classes:
            if "user" in i.lower ():
                print i
    """
    def __init__ (self, namespace, find_classes):
        _set (self, "_namespace", namespace)
        # # wmi attribute preserved for backwards compatibility #
        _set (self, "wmi", namespace)
        self._classes = None
        self._classes_map = {}
        # # Pick up the list of classes under this namespace
        # so that they can be queried, and used as though
        # properties of the namespace by means of the __getattr__
        # hook below.
        # If the namespace does not support SubclassesOf, carry on
        # regardless
        #
        if find_classes:
            _ = self.classes

虽然注释里有相关说明,但我还是搞不懂它的实现逻辑,尤其是Python类怎么能以不同的名称完成初始化?

核心问题解答:类的别名与工厂函数实现

其实这是Python里很常见的技巧,主要通过两种方式实现:

1. 类的别名赋值

模块里可能直接把内部类_wmi_namespace赋值给了对外暴露的WMI名称,比如:

# 在wmi模块的某个地方
WMI = _wmi_namespace

这样你调用wmi.WMI()的时候,本质上就是在实例化_wmi_namespace类,只是名字被替换成了更简洁友好的WMI。这种方式常用于隐藏内部实现细节,用下划线开头的类名表示这是内部私有类,对外只暴露用户需要的名字。

2. 工厂函数包装

另一种可能是模块里定义了一个名为WMI的工厂函数,它内部负责创建_wmi_namespace的实例,还能做一些额外的逻辑处理,比如默认参数设置、异常捕获等:

def WMI(namespace="root/cimv2", find_classes=True, computer_name=None, user=None, password=None):
    # 这里可以做一些参数预处理、权限验证等逻辑
    namespace_obj = _wmi_namespace(namespace, find_classes)
    # 如果需要连接远程机器,可能在这里添加额外配置
    if computer_name:
        # 处理远程连接逻辑
        pass
    return namespace_obj

这种方式比直接暴露类更灵活,能给用户提供更简洁的调用接口,同时把复杂的初始化逻辑封装在工厂函数里。

至于你看到的_wmi_namespace类的__init__方法,它接收namespace和find_classes两个参数,这说明当你调用wmi.WMI()时,传入的参数最终会传递给这个内部类的初始化方法,只是中间可能经过了工厂函数的处理(比如设置默认值)。

内容的提问来源于stack exchange,提问作者zviad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:49:42