Tom*_*ick 5 python com type-hinting
我在 python 中使用 COM 对象来向 3rd 方软件公开可编程接口。这是通过使用Dispatchfrom来实现的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
Run Code Online (Sandbox Code Playgroud)
在上面的代码片段中,我将用 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
Run Code Online (Sandbox Code Playgroud)
这不会返回用于定义 COM 对象的合适类型。我相信我可以使用TypeVar('T')and创建一个抽象基类Generic[],但是我不确定是否有更多 pythonic/更好的替代方案可用。
谢谢
恐怕您不幸遇到了使用 Python 键入的限制之一。尤其:
Dispatch确实分派到任意对象)。因此,我推荐以下三种方法之一:
如果您想对返回类型绝对不做任何假设并将其视为不透明的 blob,请让返回类型为object。这是限制性最强且类型安全的选项,因为符合 PEP 484 的类型检查器将允许调用者仅使用所有 Python 对象中存在的方法,例如__str__或__eq__。
如果您想对返回类型绝对不做任何假设,但又不想对其使用施加任何限制,请将返回类型设置为Any(动态类型)。这是最宽容和最不安全的操作:您说输出是某种动态类型,并告诉类型检查器让调用者随心所欲地使用返回的对象。
可以这么说,这是“默认选项”:由于 pywin32 没有可用的类型存根,因此类型检查器将回退到假设Dispatch(...)返回类型为 Any。
如果您确定返回类型将始终具有某些可用的特定方法或属性,则返回类型可以是Protocol。协议基本上允许您进行结构子类型化:任何碰巧实现协议方法和属性的类都被视为该协议的子类型,即使该类没有以任何方式从协议继承。如果您熟悉 Go,协议基本上就像 Go 的接口。
您可能想create_adodb_recordset(...)在此处创建专用函数,以便可以更全面地自定义返回类型。