You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()

原因分析

  1. PyInstaller自动识别为GUI程序:代码中使用了Tkinter创建图形界面,PyInstaller默认会将这类程序打包为无控制台的GUI应用,导致print和tqdm的输出没有可显示的窗口。
  2. 标准输出流重定向:打包过程中PyInstaller会修改标准输出的指向,即使手动打开终端运行exe,输出也无法正常映射到当前终端窗口。

解决方案

方案1:强制打包带控制台的exe

使用PyInstaller时添加--console(简写-c)参数,强制生成带控制台窗口的可执行文件:

pyinstaller --console your_script_name.py

运行打包后的exe时会自动弹出控制台,所有print和tqdm的进度条、输出都会正常显示在这里。

方案2:将输出写入日志文件

如果不需要控制台窗口,可以修改代码把输出写入日志文件,替代终端打印:

  1. 先导入日志模块并配置:
import logging
logging.basicConfig(
    filename='email_count_log.txt',
    level=logging.INFO,
    format='%(asctime)s - %(message)s',
    encoding='utf-8'
)
  1. 将所有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:39:19