簡體   English   中英

如何正確初始化 win32com.client.constants?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM