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

PyInstaller打包.pyw文件时tqdm.contrib.telegram的trange失效报错

问题原因

.pyw格式脚本运行时不会创建控制台窗口,导致sys.stdout和sys.stderr被设为None。而tqdm.contrib.telegram的内部实现依赖标准输出流,当尝试调用write方法时,就会触发'NoneType' object has no attribute 'write'错误。

解决方案

方案1:重定向标准输出/错误流

在代码开头导入sys和io,并在main函数初始化阶段,手动将标准输出和错误流重定向到内存对象或日志文件:

import sys
import io

def main() -> None:
    # 处理.pyw环境下的标准流缺失问题
    if sys.stdout is None:
        # 可替换为日志文件路径(如'./app.log')实现持久化日志记录
        sys.stdout = io.StringIO()
    if sys.stderr is None:
        sys.stderr = io.StringIO()
    
    # 原有业务代码保持不变
    load_dotenv()
    global config,telegram_token
    config = {
    'telegramToken': os.environ['TELEGRAM_BOT_TOKEN']
    }
    telegram_token = config['telegramToken']
    telegram_token = mycrypto.crypto(telegram_token,'decrypt')
    # ...后续代码无需修改

方案2:指定trange的输出流参数

调用trange时,手动传入一个有效的IO对象作为file参数,避免依赖默认的标准输出:

from io import StringIO

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
    chatid = update.message.chat_id
    my_df = 100
    # 创建空的StringIO对象作为替代输出流
    dummy_output = StringIO()
    for i in trange(my_df, token=telegram_token, chat_id=chatid, desc='process', miniters=5, maxinterval=200, file=dummy_output):
        sleep(0.5)

方案3:PyInstaller强制保留控制台(备选)

若可接受后台存在控制台窗口,打包时添加--console参数强制创建控制台:

pyinstaller --onefile --console your_script.pyw

此方案会打破静默运行需求,仅适用于调试或特殊场景。

验证步骤

修改代码后,重新用PyInstaller打包为.pyw格式的exe文件,发送/start命令测试进度条是否正常推送,且无报错。

内容的提问来源于stack exchange,提问作者Nguyen Nam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:17:04