首页 > 编程问答 >python 中 COM 对象的正确类型提示是什么?

python 中 COM 对象的正确类型提示是什么?

时间:2024-07-31 07:02:57浏览次数:12  
标签:python com python-typing

我在 python 中使用 COM 对象来向 3rd 方软件公开可编程接口。这是通过使用 Dispatch from win32com.client 来实现的。我的项目也一直在使用 python.3.7 中的类型提示,但是我不确定如何为了类型提示的目的定义这些 COM 对象的类型。这个问题涉及我拥有的所有 COM 对象,一个真实的例子是 Microsoft Direct X Recordset: Dispatch("ADODB.Recordset")

from win32com.client import Dispatch
def create_my_com_object_instance(input_arg: Dict[str, Union[str, float, int]]) -> <type_of_com_object_here>:
    my_instance = Dispatch("ADODB.Recordset")
    # Set attributes/call methods of this instance here ... 
    return my_instance

在上面的代码片段中,我将用 COM 对象类型替换 'type_of_com_object_here'。

My第一个想法是在实例上调用 type() 并使用返回的类型:

x = Dispatch("ADODB.Recordset")
x
Out[1]: <win32com.gen_py.Microsoft ActiveX Data Objects 6.1 Library._Recordset instance at 0x83848456>
type(x)
Out[2]: win32com.gen_py.B691E011-1797-432E-907A-4D8C69339129x0x6x1._Recordset._Recordset
x.__class__
Out[3]: win32com.gen_py.B691E011-1797-432E-907A-4D8C69339129x0x6x1._Recordset._Recordset

这不会返回用于定义 COM 对象的合适类型。我相信我可以使用 TypeVar('T') Generic[] 创建一个抽象基类,但是我不确定是否有更多Pythonic/更好的替代方案可用。

谢谢


虽然可以使用 TypeVar Generic 来创建包装类型提示,但对于 COM 对象来说,这可能变得复杂且麻烦。 这是因为 win32com 为每个 COM 对象动态生成包装器类,这些类通常不是以直接方式继承的。

实用方法:

对于 COM 对象的类型提示,最实用且最不易出错的方法是使用 object Any 。这不会提供特定的类型信息,但会让 MyPy 和其他类型检查器知道它是一个对象,你可以调用属性和方法,而不会产生错误。

from typing import Any

def create_my_com_object_instance(input_arg: dict[str, str | float | int]) -> Any:
    my_instance = Dispatch("ADODB.Recordset")
    # ...
    return my_instance

优点:

  • 简单: 不需要复杂的类型定义。
  • 兼容性: win32com 的动态特性很好地配合。

缺点:

  • 没有类型安全: 你会失去 COM 对象的类型检查优势。

其他选择:

  • Protocol(协议): 如果需要更严格的类型检查,并且你正在与多个 COM 对象交互,则可以定义一个 Protocol 来描述常用方法和属性。但是,这需要更多工作,并且可能无法涵盖所有情况。

  • 存根文件: 为生成的 win32com 包装器创建存根文件 ( *.pyi ) 可以提供更精确的类型信息。但这需要深入了解 win32com 的内部工作原理,并且可能难以维护。

总的来说,对于大多数情况,使用 object Any 是最实用的方法。如果需要更强的类型安全,请考虑使用 Protocol 或存根文件,但要权衡所涉及的复杂性和维护成本。

标签:python,com,python-typing
From: 60299702

相关文章

  • 如何遍历Python字典同时避免KeyErrors?
    解析大型JSON时,某些键可能仅在某些情况下存在,例如出现错误时。从服务器的API获取200OK的情况并不少见,但是您得到的响应包含应检查的错误。处理此问题的最佳方法是什么?我知道使用类似||之类的东西。|是处理KeyError的一种方法。get()但是如果......
  • Python 中的递归数据类型
    Python中最接近Haskell中的递归数据类型的是什么?(即在定义自身时使用类型自己的定义。)编辑:为了给出递归类型的更具体定义,下面是Haskell中的二叉树:dataTreea=Leafa|Branch(Treea)(Treea)我的阅读方式如下:二叉树可以是叶子,也可以包含两......
  • 如何在Python中平滑相邻的多边形?
    我正在寻找一种平滑多边形的方法,以便相邻/接触的多边形保持接触。单个多边形可以轻松平滑,例如使用PAEK或Bezier插值(https://pro.arcgis.com/en/pro-app/latest/tool-reference/cartography/smooth-polygon.htm),这自然会改变它们的边界边缘。但是如何平滑所有多边形......
  • Python多处理池不启动多个进程
    我正在尝试使用多处理池来创建多个进程。我有一个工作函数dummy_proc定义如下:importrefrommultiprocessingimportPooldefregex_check(input_string):#Patterntomatchboth"pm_lat"and"pm_lon_coslat"followedbytwofloatspattern=r"(c......
  • 迟滞建模作为 Python GEKKO 中 MPC 的控制约束
    我试图使用PythonGEKKO在用于控制信号调度的MPC优化问题中引入滞后约束。这已成为一项艰巨的任务,因为我无法将以下问题转换为GEKKO理解的方程。问题:如果开启时间<最短开启时间,则给定资产的控制调度不应将其关闭。如果关闭时间<最小关闭时间......
  • 在 Lambda Python 中获取 errorMessage": "期望值: 第 1 行第 1 列 (char 0)"
    我正在尝试使用slackapi和awslambda函数创建一个slack机器人。现在我只希望每当用户说“你好”时它就响应“你好”。当我在Lambda代码编辑器中测试代码时,出现此错误。我对Lambda很陌生,并且已经被困在这个问题上有一段时间了。非常感谢任何帮助!完整错误:Response......
  • 具有 Python lambda 函数的 QTimer 使用先前的数据运行
    我有一个GUI项目,它使用PySide2和Python3.8,它在QThread中执行一些后台任务。在该QThread中,我有QTimer成员对象,该对象必须定期运行一个函数,每次向其传递不同的数据。我没有使用QTimer.singleShot静态函数,因为如果需要某些特定场景,我需要......
  • 我如何在 python 上使用 spire.pdf 修复此错误
    我使用spirepdf,但出现以下错误:“DllNotFound_Windows,libSkiaSharp,Nosepuedeencontrarelmóduloespecificado.:....”defextract_text_from_pdf(file_path,output_file):#LoadaPDFdocumentdoc=PdfDocument()doc.LoadFromFile(file_path)ex......
  • C++ 函数返回极其缓慢,远慢于功能等效的 python 代码
    我有一个在我编写的脚本中使用的函数,用于从列表中删除多余的阻塞关键字。基本上,输入(以任何顺序):{"apple","bapple","banana","cherry","bananaman","sweetherrypie","sweet","b"}它应该输出一个缩小的字符串数组(以任何顺序):......
  • 在预定时间从 python telegram bot 发起对话
    对于没有提供代码,我提前表示歉意。我明天会尝试添加它,但我现在还没有接近它,思考如何解决这个问题让我一直在思考。我已经为一个机器人创建了一个程序,该程序的数据帧充满了之前请求的用户添加到机器人的消息列表中。现在,机器人使用job_queue在一天中的随机时间向每个用户发......