python cmd 窗口 中文亂碼 解決方法 (附:打印不同顏色)


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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM