Python Outlook统计程序PyInstaller打包后终端无输出问题咨询
问题:PyInstaller打包exe后终端无输出(原Python脚本运行正常)
本人开发的Outlook邮件统计Python程序,直接运行.py文件时可正常在终端打印日期、邮件计数等输出;但使用PyInstaller打包为exe后,终端无法显示这些输出。
程序代码
import win32com.client from collections import defaultdict from datetime import datetime, date from tqdm import tqdm import pytz from datetime import datetime, timedelta from tkinter import * counts = [] dates = [] def outlookc(): outlook = win32com.client.Dispatch("Outlook.Application") explorer = outlook.ActiveExplorer() if explorer is not None: folder = explorer.CurrentFolder utc = pytz.UTC date = datetime(int(e1.get()), int(e2.get()), int(e3.get())) start_date = utc.localize(date) end_date = start_date + timedelta(days=int(e4.get())) restriction = f"[ReceivedTime] >= '{start_date.strftime('%m/%d/%Y %H:%M %p')}' AND [ReceivedTime] < '{end_date.strftime('%m/%d/%Y %H:%M %p')}'" filtered_items = folder.Items.Restrict(restriction) emails_by_date = defaultdict(list) for item in tqdm(filtered_items, desc="Counting emails"): if item.Class == 43: try: received_date = item.ReceivedTime.date() emails_by_date[received_date].append(item) except: pass else: print(f" Ezt nem számolja bele: {item.Subject}") pass for received_date, emails in sorted(emails_by_date.items()): count = len(emails) dates.append(received_date.strftime("%Y-%m-%d")) counts.append(count) print(f"{received_date}: {count}") else: print("Nem találok aktív mappát.") master = Tk() master.geometry("300x300") master.title(" Outlook e-mail counter ") master.attributes('-topmost',True) Label(master, text="Kezdő év():").grid(row=0) Label(master, text="Kezdő hó").grid(row=1) Label(master, text="Kezdő nap").grid(row=2) Label(master, text="Hány napot").grid(row=3) Label(master, text="*2023").grid(row=0, column=2) Label(master, text="*2").grid(row=1, column=2) Label(master, text="*8").grid(row=2, column=2) Label(master, text="*1").grid(row=3, column=2) e1 = Entry(master) e2 = Entry(master) e3 = Entry(master) e4 = Entry(master) e1.grid(row=0, column=1) e2.grid(row=1, column=1) e3.grid(row=2, column=1) e4.grid(row=3, column=1) Button(master, text='Számol', command=outlookc).grid(row=5, column=1, sticky=W, pady=4) master.mainloop()
原因分析
- PyInstaller自动识别为GUI程序:代码中使用了Tkinter创建图形界面,PyInstaller默认会将这类程序打包为无控制台的GUI应用,导致
print和tqdm的输出没有可显示的窗口。 - 标准输出流重定向:打包过程中PyInstaller会修改标准输出的指向,即使手动打开终端运行exe,输出也无法正常映射到当前终端窗口。
解决方案
方案1:强制打包带控制台的exe
使用PyInstaller时添加--console(简写-c)参数,强制生成带控制台窗口的可执行文件:
pyinstaller --console your_script_name.py
运行打包后的exe时会自动弹出控制台,所有print和tqdm的进度条、输出都会正常显示在这里。
方案2:将输出写入日志文件
如果不需要控制台窗口,可以修改代码把输出写入日志文件,替代终端打印:
- 先导入日志模块并配置:
import logging logging.basicConfig( filename='email_count_log.txt', level=logging.INFO, format='%(asctime)s - %(message)s', encoding='utf-8' )
- 将所有
print语句替换为logging.info:
# 替换前:print(f"{received_date}: {count}") # 替换后: logging.info(f"{received_date}: {count}") # 替换前:print("Nem találok aktív mappát.") # 替换后: logging.info("Nem találok aktív mappát.")
额外优化:tqdm输出兼容
如果使用方案1,tqdm在打包后的控制台可能显示异常,可以指定输出流为标准输出:
import sys # 修改tqdm循环行 for item in tqdm(filtered_items, desc="Counting emails", file=sys.stdout):
内容的提问来源于stack exchange,提问作者Patrik Fodor
相关产品推荐
相关产品推荐

