繁体   English   中英

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

[英]What is the correct type hinting for COM Objects in python?

我在 python 中使用 COM 对象来向 3rd 方软件公开可编程接口。 这是通过使用来自win32com.client Dispatch实现的。 我的项目也一直在使用来自 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”。

我的第一个想法是在实例上调用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/更好的替代方案可用。

谢谢

恐怕您不幸遇到了在 Python 中输入的限制之一。 特别是:

  1. 据我所知,无论是 Typeshed 还是作为 3rd 方模块,pywin32 库都没有类型存根。 这意味着没有关于该类型应该是什么的现有规范参考。
  2. 动态分派到任意对象将限制使用类型提示表达的内容(假设Dispatch确实分派到任意对象)。

因此,我推荐以下三种方法之一:

  1. 如果您想对返回的类型完全不做任何假设并将其视为不透明的 blob,请将返回类型设为object 这是最具限制性和类型安全的选项,因为符合 PEP 484 的类型检查器将让调用者仅使用所有 Python 对象中存在的方法,例如__str____eq__

  2. 如果您想对返回的类型完全不做任何假设,但也不对其使用施加任何限制,请将返回类型设为Any ,即动态类型。 这是最宽松和最不安全的操作:您说输出是某种动态类型,并告诉类型检查器让调用者随意使用返回的对象。

    这是“默认选项”,可以这么说:由于 pywin32 没有可用的类型存根,类型检查器将回退到假设Dispatch(...)的返回类型为 Any。

  3. 如果您确定返回的类型总是有一些特定的方法或属性可用,则返回类型为Protocol 协议基本上允许您进行结构子类型化:任何碰巧实现协议方法和属性的类都被视为该协议的子类型,即使该类没有以任何方式从协议继承。 如果您熟悉 Go,协议基本上就像 Go 的接口。

    您可能希望在此处创建一个专用的create_adodb_recordset(...)函数,以便您可以更全面地自定义返回类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM