[英]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.