亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Outlook 中處理數千封電子郵件時內存不足,如何釋放 COM 對象的內存?

Outlook 中處理數千封電子郵件時內存不足,如何釋放 COM 對象的內存?

呼啦一陣風 2023-07-18 13:38:29
我有一個 Python 腳本,可以獲取收件箱文件夾中所有電子郵件的電子郵件 ID。但是,當 Outlook 達到數千封電子郵件時,會引發內存不足異常。例外:Printing emails...Traceback (most recent call last):  File "print_emails.py", line 53, in main    print_emails()  File "print_emails.py", line 43, in print_emails    primary_emails, primary_email_ids = get_emails_and_ids(primary_source_folder)  File "print_emails.py", line 29, in get_emails_and_ids    property_accessor = item.PropertyAccessor  File "C:\Program Files\Python38\lib\site-packages\win32com\client\__init__.py", line 474, in __getattr__    return self._ApplyTypes_(*args)  File "C:\Program Files\Python38\lib\site-packages\win32com\client\__init__.py", line 467, in _ApplyTypes_    self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, *args),pywintypes.com_error: (-2147352567, 'Exception occurred.', (4096, 'Microsoft Outlook', 'Out of memory or system resources. Close some windows or programs and try again.', None, 0, -2147024882), None)Press enter to exit...我嘗試了兩種不同的方法:迭代一次(get_emails_and_ids)和兩次(get_emails和get_email_ids)。PropertyAccessor似乎和獲得了幾千次有關。如果我只是使用 來獲取電子郵件get_emails,它在處理 38,000 封電子郵件時運行良好,但是當我開始使用數千次來獲取 ID 時PropertyAccessor,內存就會耗盡。我必須釋放舊的屬性訪問器嗎?安裝:pip install -U pypiwin32代碼:#!/usr/bin/env pythonfrom typing import Any, List, Tuple, Setimport tracebackimport win32com.clientPidTagInternetMessageId = "http://schemas.microsoft.com/mapi/proptag/0x1035001F"primary_account_email = "[email protected]"primary_source_folder_name = "Inbox"def get_emails(folder) -> List:    return [item for item in folder.Items if "_MailItem" in str(type(item))]def get_email_ids(emails) -> Set[str]:    return {email_id for email in emails if len(email_id := email.PropertyAccessor.GetProperty(PidTagInternetMessageId)) > 0}
查看完整描述

2 回答

?
慕娘9325324

TA貢獻1783條經驗 獲得超4個贊

嘗試將“ for”循環替換為從 1 到 Items.Count 的循環(使用 Items(i) 檢索項目) - 不確定 Python,但在其他語言中,“ ”foreach循環傾向于保留引用的集合的所有項目,直到循環退出。



查看完整回答
反對 回復 2023-07-18
?
12345678_0001

TA貢獻1802條經驗 獲得超5個贊

我的解決方案是不將所有電子郵件(MailItem 對象)存儲在列表中。如果我需要列表中的電子郵件,當我處理電子郵件時,我應該list.pop()立即將其從列表中刪除。使用PropertyAccessor并將電子郵件保留在列表中會導致 Outlook 將對象保留在內存中,并導致 Outlook 內存不足。


我擺脫了get_emails和get_emails_and_ids函數并重新編寫了該get_email_ids函數以僅存儲電子郵件消息 ID,但不將電子郵件對象存儲在列表中:


def get_email_ids(folder) -> Tuple[Set[str], int]:

    email_ids = set()


    items = folder.Items

    i = 0

    for item in items:

        if "_MailItem" in str(type(item)):

            i += 1


            property_accessor = item.PropertyAccessor

            email_id = property_accessor.GetProperty(PidTagInternetMessageId)

            if len(email_id) > 0:

                email_ids.add(email_id)


            if i % 500 == 0:

                print(f"    Retrieved {i} email IDs.")


    return email_ids, i

我編寫的另一個腳本現在快了很多,至少需要 10 分鐘。以前,它每秒處理幾封電子郵件,需要幾個小時。


查看完整回答
反對 回復 2023-07-18
  • 2 回答
  • 0 關注
  • 225 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號