代码之家  ›  专栏  ›  技术社区  ›  Tony Veijalainen

Unicode未正确打印到cp850(cp437),适合玩卡

  •  3
  • Tony Veijalainen  · 技术社区  · 15 年前

    总结:如何独立打印unicode系统以生成扑克牌符号?

    我做错了什么,我认为自己相当流利的Python,除了我似乎无法正确打印!

    # coding: utf-8
    from __future__ import print_function
    from __future__ import unicode_literals
    import sys
    
    symbols = ('♥','♦','♠','♣')
    # red suits to sdterr for IDLE
    print(' '.join(symbols[:2]), file=sys.stderr)
    print(' '.join(symbols[2:]))
    
    sys.stdout.write(symbols) # also correct in IDLE
    print(' '.join(symbols))
    

    打印到控制台,这是控制台应用程序的主要用途,失败得很惨,尽管:

    J:\test>chcp
    Aktiivinen koodisivu: 850
    
    
    J:\test>symbol2
    Traceback (most recent call last):
      File "J:\test\symbol2.py", line 9, in <module>
        print(''.join(symbols))
      File "J:\Python26\lib\encodings\cp850.py", line 12, in encode
        return codecs.charmap_encode(input,errors,encoding_map)
    UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-3: character maps to <unde
    fined>
    J:\test>chcp 437
    Aktiivinen koodisivu: 437
    
    J:\test>d:\Python27\python.exe symbol2.py
    Traceback (most recent call last):
      File "symbol2.py", line 6, in <module>
        print(' '.join(symbols))
      File "d:\Python27\lib\encodings\cp437.py", line 12, in encode
        return codecs.charmap_encode(input,errors,encoding_map)
    UnicodeEncodeError: 'charmap' codec can't encode character u'\u2660' in position 0: character maps
    o <undefined>
    
    J:\test>
    

    所以summa summarum我有一个控制台应用程序,只要您不使用控制台,而是空闲,它就可以工作。

    当然,我可以通过chr自己生成符号:

    # correct symbols for cp850
    print(''.join(chr(n) for n in range(3,3+4)))
    

    但这样做看起来很愚蠢。我也不会让程序只在Windows上运行,也不会有很多特殊情况(比如条件编译)。我想要可读的代码。

    我不介意它输出哪个字母,只要它看起来是正确的,不管它是诺基亚手机、Windows还是Linux。 Unicode应该这样做,但它不能正确地打印到控制台

    4 回复  |  直到 15 年前
        1
  •  1
  •   Mark Tolonen    15 年前

    使用Unicode字符串和 codecs 模块:

    或者:

    # coding: utf-8
    from __future__ import print_function
    import sys
    import codecs
    
    symbols = (u'♠',u'♥',u'♦',u'♣')
    
    print(u' '.join(symbols))
    print(*symbols)
    with codecs.open('test.txt','w','utf-8') as testfile:
        print(*symbols, file=testfile)
    

    或:

    # coding: utf-8
    from __future__ import print_function
    from __future__ import unicode_literals
    import sys
    import codecs
    
    symbols = ('♠','♥','♦','♣')
    
    print(' '.join(symbols))
    print(*symbols)
    with codecs.open('test.txt','w','utf-8') as testfile:
        print(*symbols, file=testfile)
    

    无需重新实施 print .

        2
  •  2
  •   Fredrik Pihl    15 年前

    每当我需要输出utf-8字符时,我使用以下方法:

    import codecs
    
    out = codecs.getwriter('utf-8')(sys.stdout)
    
    str = u'♠'
    
    out.write("%s\n" % str)
    

    这帮我省了 encode('utf-8') 每次有东西需要发送到sdtout/stderr。

        3
  •  1
  •   Community Mohan Dere    9 年前

    对最新问题的答复

    因为您要做的只是在CMD上打印UTF-8字符,所以运气不好,CMD不支持UTF-8:
    Is there a Windows command shell that will display Unicode characters?

    旧答案

    现在还不完全清楚你想在这里做什么,我敢打赌你想写 编码的 一个文件的UTF-8。

    你的问题是:

    1. symbols = ('♠','♥', '♦','♣') 虽然您的文件编码可能是UTF-8,但除非您使用Python 3,否则默认情况下字符串不是UTF-8,您需要在它们前面加上一个 u :
      symbols = (u'♠', u'♥', u'♦', u'♣')

    2. 你的 str(arg) 将unicode字符串转换回普通字符串,只需省略或使用 unicode(arg) 转换为unicode字符串

    3. 命名 .decode() 可能有点混乱,这会将字节解码为UTF-8,但您需要做的是 编码 将UTF-8转换为字节以便使用 .encode()

    4. 不是以二进制模式写入文件,而是 open('test.txt', 'w') 你需要使用 open('test.txt', 'wb') (注意 wb )这将以二进制模式打开文件,这在windows上很重要

    如果我们把所有这些放在一起,我们会得到:

    # -*- coding: utf-8 -*-
    from __future__ import print_function
    import sys
    
    symbols = (u'♠',u'♥', u'♦',u'♣')
    
    print(' '.join(symbols))
    print('Failure!')
    
    def print(*args,**kwargs):
        end = kwargs[end] if 'end' in kwargs else '\n'
        sep = kwargs[sep] if 'sep' in kwargs else ' '
        stdout = sys.stdout if 'file' not in kwargs else kwargs['file']
        stdout.write(sep.join(unicode(arg).encode('utf-8') for arg in args))
        stdout.write(end)
    
    print(*symbols)
    print('Success!')
    with open('test.txt', 'wb') as testfile:
        print(*symbols, file=testfile)
    

    快乐地写下字节 编码的 文件的UTF-8(至少在我的Ubuntu框中)。

        4
  •  0
  •   tzot    15 年前

    Windows控制台中的UTF-8是一个漫长而痛苦的故事。

    你可以阅读 issue 1602 issue 6058 有一些有用的东西,或多或少,但它是脆弱的。

    让我总结一下:

    • 在中添加“cp65001”作为“utf8”的别名 Lib/encodings/aliases.py
    • 选择 Lucida Console Consolas 作为您的控制台字体
    • 运行 chcp 65001
    • 运行python