[英]How to properly initialize win32com.client.constants?
我正在编写一个简单的 email 过滤器来处理 Windows 10 上的 Outlook 传入消息,并试图使用 Anaconda 下的win32com
库在 Python 中对其进行编码。我还试图避免在“收件箱”中使用幻数在其他示例中,宁愿使用应在win32com.client.constants
下定义的常量。 但是我遇到了令人惊讶的简单错误:
因此,我大致基于https://stackoverflow.com/a/65800130/257924编写了以下简单代码:
import sys
import win32com.client
try:
outlookApp = win32com.client.Dispatch("Outlook.Application")
except:
print("ERROR: Unable to load Outlook")
sys.exit(1)
outlook = outlookApp.GetNamespace("MAPI")
ofContacts = outlook.GetDefaultFolder(win32com.client.constants.olFolderContacts)
print("ofContacts", type(ofContacts))
sys.exit(0)
在基于 Anaconda 的安装程序(Anaconda3 2022.10(Python 3.9.13 64 位))下运行 Windows 出现 10 个错误:
(base) c:\Temp>python testing.py
Traceback (most recent call last):
File "c:\Temp\testing.py", line 11, in <module>
ofContacts = outlook.GetDefaultFolder(win32com.client.constants.olFolderContacts)
File "C:\Users\brentg\Anaconda3\lib\site-packages\win32com\client\__init__.py", line 231, in __getattr__
raise AttributeError(a)
AttributeError: olFolderContacts
进一步调试发现,上述错误信息中的__init__.py
引用了__dicts__
属性。 请参阅下面的 class 的摘录。 出于某种原因, __dicts__
是一个空列表:
class Constants:
"""A container for generated COM constants."""
def __init__(self):
self.__dicts__ = [] # A list of dictionaries
def __getattr__(self, a):
for d in self.__dicts__:
if a in d:
return d[a]
raise AttributeError(a)
# And create an instance.
constants = Constants()
让win32com
正确初始化constants
object 需要什么?
如果相关, init .py 文件上的时间戳显示 10/10/2021。
简短的回答是改变:
outlookApp = win32com.client.Dispatch("Outlook.Application")
到
outlookApp = win32com.client.gencache.EnsureDispatch("Outlook.Application")
更长的答案是win32com
可以通过以下两种方式之一使用 COM 接口: late-
绑定和early-binding
。
使用late-binding
,您的代码对 Dispatch 接口一无所知。 不知道哪些方法、属性或常量可用。 当您调用 Dispatch 接口上的方法时, win32com
不知道该方法是否存在或任何参数:它只是发送给定的内容并希望最好!
使用early-binding
,您的代码依赖于先前捕获的有关 Dispatch 接口的信息,这些信息取自其类型库。 此信息用于为知道所有方法及其参数的接口创建本地 Python 包装器。 同时,它使用类型库中包含的任何常量/枚举填充常量字典。
win32com
有一个包罗万象的win32com.client.Dispatch()
function 如果存在本地包装文件,它将尝试使用早期绑定,否则将退回到使用后期绑定。 我对 package 的问题是呼叫者并不总是知道他们得到了什么,就像 OP 的情况一样。
替代方案win32com.client.gencache.EnsureDispatch()
function 强制执行早期绑定并确保任何常量可用。 如果本地包装文件不可用,将创建它们(您可能会在 %LOCALAPPDATA%\Temp\gen_py\xx\CLSID 下找到它们,其中 xx 是 Python 版本号,CLSID 是类型库的 GUID)。 一旦创建了这些包装器,通用win32com.client.Dispatch()
将使用这些文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.