Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 945|回复: 3

python cmd 窗口 中文乱码 解决方法 (附:打印不同颜色)

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-5-30 11:46:49 | 显示全部楼层 |阅读模式

    python cmd 窗口 中文乱码 解决方法 (附:打印不同颜色)

    前言

    在 python 开发中,有时候想通过cmd窗口来和用户交互,比如显示信息之类的,会比自己创建 GUI 来的方便,但是随之而来的就是编码乱码问题

    下面例子在 python2 和 python3 中都可以运行,也可以在其它 .py 中通过 import os;os.startfile(ur"xxx.bat") 来运行

    之前一直遇到一个问题,通过双击 bat 文件来运行,可以不用转码,只要 cmd 窗口的活动页编码是 936 就可以了,但是在其它 py 文件中运行那个 bat,就会出现乱码,所以转码后可以一保正常

    双击 .bat 来运行 py

    @echo off
    chcp 936>nul
    python d:\test.py exit
    # -*- coding: utf-8-*-
    
    import sys
    import os
    
    input_ = input
    zh_coding = 'cp936'
    utf_8 = 'utf-8'
    
    # before other codes
    if sys.version_info.major < 3:
        reload(sys)
        sys.setdefaultencoding(utf_8)
        
        input_ = raw_input
    
    # begin your code
    
    def to936(utf8):
        if sys.version_info.major < 3:
            utf8 = utf8.decode().encode(zh_coding)
        return utf8
    
    def toUtf8(zh936):
        if sys.version_info.major < 3:
            zh936 = zh936.decode(zh_coding).encode(utf_8)
        return zh936
    
    os.system('@echo off')
    # 转换cmd窗口的编码集,不管cmd窗口的默认值是什么都显示正确
    os.system('chcp 936 >nul')
    
    print(to936(u'中文简体(encoding)'))
    print(to936(u'中文繁體(encoding)'))
    
    # 在 cmd 窗口 的默认值的默认代码页不是 936 的情况下会报错。
    # 如果是 936,通过双击 .bat 运行是正常的,
    # 如果在其它 py 中通过 os.startfile(), subprocess, os.system()
    # 等模块来运行那个bat,会显示乱码
    try:
        print(u'中文简体(not encoding)')
        print(u'中文繁體(not encoding)')
    except Exception as e:
        os.system(to936(u'echo 解码错误'))
        print(e)
    
    i = input_(to936(u'输入你的中文名字:'))
    i = toUtf8(i)
    msg = to936(u'你的中文名字是:%s' % i)
    print(msg)
    
    os.system('pause && exit')

     打印不同颜色

    win 的 cmd 终端也可以像linux的终端一样,打印不同行颜色,同一行不同颜色

    这里有个个方法:https://www.cnblogs.com/linyfeng/p/8286506.html#4304331

    不过,在我使用 waf 的过程中,发现 waf 在win cmd 窗口打印颜色更全面更通用的模块,使用方法和linux的一致

    waf 是开源的,我从里面提取了相关的模块,可以集成到自己 lib 中,waf 教程和下载:https://waf.io/book/

    而且,使用 waf 的模块,在 python 2 中只是print 的时候,不用转码,但是input的时候还是要转回utf-8

    waf 从 git 上下载的 waflib 兼容 python 2 和 3

    waflib模块中提取的文件(注意,这些文件的编写,语法缩进是 tab,而不是四个空格,所以最好自己把 tab 替换成四个空格,不然通过编译出来的 pyc 可能不能用):

    __init__.py

    ansiterm.py

    Errors.py

    Utils.py

    # -*- coding: utf-8-*-
    
    import sys
    import os
    
    input_ = input
    zh_coding = 'cp936'
    utf_8 = 'utf-8'
    
    # before other codes
    if sys.version_info.major < 3:
        reload(sys)
        sys.setdefaultencoding(utf_8)
    
    # begin your code ###################################################
    
    from waflib import ansiterm
    
    if not os.environ.get('NOSYNC',False):
        if sys.stdout.isatty()and id(sys.stdout)==id(sys.__stdout__):
            sys.stdout=ansiterm.AnsiTerm(sys.stdout)
        if sys.stderr.isatty()and id(sys.stderr)==id(sys.__stderr__):
            sys.stderr=ansiterm.AnsiTerm(sys.stderr)
    
    os.system('@echo off')
    # 转换cmd窗口的编码集,不管cmd窗口的默认值是什么都显示正确
    os.system('chcp 936 >nul')
    
    # 颜色
    print(u'\033[32m绿色\033[31m红色\033[0m')
    
    print(u'中文简体(not encoding)')
    print(u'中文繁體(not encoding)')
    
    os.system('pause && exit')

    上面没有 input 例子,如果要用,参考上上个例子

    主要添加了以下代码,之后 print 就像通用的一样使用就可以了

    from waflib import ansiterm
    
    if not os.environ.get('NOSYNC',False):
        if sys.stdout.isatty()and id(sys.stdout)==id(sys.__stdout__):
            sys.stdout=ansiterm.AnsiTerm(sys.stdout)
        if sys.stderr.isatty()and id(sys.stderr)==id(sys.__stderr__):
            sys.stderr=ansiterm.AnsiTerm(sys.stderr)

     print 颜色 格式参考:https://www.cnblogs.com/pupilheart/p/9704943.html

     

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2021-4-2 17:27
  • 签到天数: 1 天

    [LV.1]初来乍到

    0

    主题

    658

    帖子

    123

    积分

    新手用户

    Rank: 1

    积分
    123
    发表于 2021-6-28 08:35:07 | 显示全部楼层
    支持一下,期待更多东西
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 21:43 , Processed in 0.065950 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表