Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python、Unicode和Windows控制台_Python_Unicode - Fatal编程技术网

Python、Unicode和Windows控制台

Python、Unicode和Windows控制台,python,unicode,Python,Unicode,当我试图在Windows控制台中打印Unicode字符串时,我得到一个错误 UnicodeEncodeError:“charmap”编解码器无法对字符进行编码 我认为这是因为Windows控制台不接受仅Unicode字符。最好的解决办法是什么? 有没有什么方法可以让Python自动打印一个文件?而不是在这种情况下失败 编辑:我正在使用Python 2.5 注:@LasseV.Karlsen带有复选标记的答案从2008年起就有点过时了。请小心使用下面的解决方案/答案/建议 从今天到2016年1月6

当我试图在Windows控制台中打印Unicode字符串时,我得到一个错误

UnicodeEncodeError:“charmap”编解码器无法对字符进行编码

我认为这是因为Windows控制台不接受仅Unicode字符。最好的解决办法是什么? 有没有什么方法可以让Python自动打印一个文件?而不是在这种情况下失败

编辑:我正在使用Python 2.5

注:@LasseV.Karlsen带有复选标记的答案从2008年起就有点过时了。请小心使用下面的解决方案/答案/建议

从今天到2016年1月6日更为相关。

注意:这个答案与2008年相比有些过时。请小心使用下面的解决方案

这是一个详细说明问题和解决方案的页面。请在该页面中搜索将sys.stdout包装到实例中的文本:

以下是该页面的代码摘录:

$ python -c 'import sys, codecs, locale; print sys.stdout.encoding; \
    sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); \
    line = u"\u0411\n"; print type(line), len(line); \
    sys.stdout.write(line); print line'
  UTF-8
  <type 'unicode'> 2
  Б
  Б

  $ python -c 'import sys, codecs, locale; print sys.stdout.encoding; \
    sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); \
    line = u"\u0411\n"; print type(line), len(line); \
    sys.stdout.write(line); print line' | cat
  None
  <type 'unicode'> 2
  Б
  Б

该页面上还有更多信息,值得一读。

问题的原因不是Win控制台不愿意接受Unicode,因为我猜默认情况下Win2k是这样的。这是默认的系统编码。试试这段代码,看看它能给你什么:

import sys
sys.getdefaultencoding()
如果它说ascii,那就是你的原因- 您必须创建一个名为sitecustomize.py的文件,并将其放在python路径下。我将其放在/usr/lib/python2.5/site-packages下,但这与Win不同,它是c:\python\lib\site-packages或其他文件,具有以下内容:

import sys
sys.setdefaultencoding('utf-8')
也许您还需要在文件中指定编码:

# -*- coding: UTF-8 -*-
import sys,time

编辑:可以找到更多信息

下面的代码将使Python作为UTF-8输出到控制台,即使在Windows上也是如此

在Windows 7上,控制台可以很好地显示字符,但在Windows XP上,它不能很好地显示字符,但至少它可以工作,最重要的是,在所有平台上,脚本的输出都是一致的。您将能够将输出重定向到文件

下面的代码是在Windows上用Python 2.6测试的


#!/usr/bin/python
# -*- coding: UTF-8 -*-

import codecs, sys

reload(sys)
sys.setdefaultencoding('utf-8')

print sys.getdefaultencoding()

if sys.platform == 'win32':
    try:
        import win32console 
    except:
        print "Python Win32 Extensions module is required.\n You can download it from https://sourceforge.net/projects/pywin32/ (x86 and x64 builds are available)\n"
        exit(-1)
    # win32console implementation  of SetConsoleCP does not return a value
    # CP_UTF8 = 65001
    win32console.SetConsoleCP(65001)
    if (win32console.GetConsoleCP() != 65001):
        raise Exception ("Cannot set console codepage to 65001 (UTF-8)")
    win32console.SetConsoleOutputCP(65001)
    if (win32console.GetConsoleOutputCP() != 65001):
        raise Exception ("Cannot set console output codepage to 65001 (UTF-8)")

#import sys, codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
sys.stderr = codecs.getwriter('utf8')(sys.stderr)

print "This is an Е乂αmp١ȅ testing Unicode support using Arabic, Latin, Cyrillic, Greek, Hebrew and CJK code points.\n"

尽管其他听起来似乎合理的答案建议将代码页更改为65001,但这一点仍然存在。此外,使用sys.setdefaultencoding更改默认编码也很重要


有关详细信息和确实有效的代码,请参阅。

如果您对获取错误字符的可靠表示不感兴趣,可以使用类似于python>=2.6的代码,包括3.x:

from __future__ import print_function
import sys

def safeprint(s):
    try:
        print(s)
    except UnicodeEncodeError:
        if sys.version_info >= (3,):
            print(s.encode('utf8').decode(sys.stdout.encoding))
        else:
            print(s.encode('utf8'))

safeprint(u"\N{EM DASH}")

字符串中的错误字符将转换为可由Windows控制台打印的表示形式。

更新:实现:Windows上的默认控制台现在将接受所有Unicode字符。在内部,它使用与相同的Unicode API。printunicode_字符串现在应该可以工作了

我得到了一个Unicodeincoder错误:“charmap”编解码器无法对字符进行编码。。。错误

该错误意味着您尝试打印的Unicode字符无法使用当前的chcp控制台字符编码表示。代码页通常是8位编码,例如cp437,它只能表示~1M Unicode字符中的~0x100个字符:

>>> u"\N{EURO SIGN}".encode('cp437') Traceback (most recent call last): ... UnicodeEncodeError: 'charmap' codec can't encode character '\u20ac' in position 0: character maps to 看

有什么方法可以让我制作Python吗 自动打印?而不是在这种情况下失败

是否足以将所有不可编码字符替换为?在您的情况下,您可以设置:


在Python3.6+中,交互控制台缓冲区将忽略PythonionEncoding envvar指定的编码,除非PYTHONLEGACYWINDOWSIOENCODING envvar设置为非空字符串。

与J.F.Sebastian的答案相关,但更直接

如果在打印到控制台/终端时遇到此问题,请执行以下操作:

>set PYTHONIOENCODING=UTF-8

就像Giampaolo Rodolá的回答,但更肮脏的是:我真的,真的打算很快花很长时间理解编码的整个主题,以及它们如何应用于Windoze控制台

目前我只想要sthg,这意味着我的程序不会崩溃,我明白。。。而且这也不涉及导入太多的外来模块,特别是我使用的是Jython,所以有一半的时间Python模块实际上是不可用的

def pr(s):
    try:
        print(s)
    except UnicodeEncodeError:
        for c in s:
            try:
                print( c, end='')
            except UnicodeEncodeError:
                print( '?', end='')
NB pr打字比打印短,打字比safeprint短很多

詹姆斯·苏拉克问道

有没有什么方法可以让Python自动打印一个文件?而不是在这种情况下失败

其他解决方案建议我们尝试修改Windows环境或替换Python的打印功能。下面的答案更接近于满足苏拉克的要求

在Windows 7下,可以使Python 3.5打印Unicode而不抛出Unicode错误,如下所示:

代替: 打印文本 替换: printstrtext.编码为“utf-8”

Python现在不再抛出异常,而是将不可打印的Unicode字符显示为\xNN十六进制代码,例如:

Halmalo n\xe2\x80\x99\xc3\xa9tait plus qu\xe2\x80\x99un黑点

而不是

Halmalo n'était加qu'un point noir

当然,后者是我的 在其他条件相同的情况下,前者更可取,但在其他情况下,前者对于诊断信息是完全准确的。因为它将Unicode显示为文字字节值,所以前者还可以帮助诊断编码/解码问题


注意:上面的str调用是必需的,因为否则encode会导致Python拒绝Unicode字符作为数字元组。

Python 3.6 windows7:有几种启动Python的方法,您可以使用带有Python徽标的Python控制台,也可以使用写有cmd.exe的windows控制台

我无法在windows控制台中打印utf8字符。打印utf-8字符会引发以下错误:

OSError: [winError 87] The paraneter is incorrect 
Exception ignored in: (_io-TextIOwrapper name='(stdout)' mode='w' ' encoding='utf8') 
OSError: [WinError 87] The parameter is incorrect 
在尝试并未能理解上述答案后,我发现这只是一个设置问题。右键单击cmd控制台窗口顶部,在字体选项卡上选择lucida console。

对于Python 2,请尝试:

print unicode(string, 'unicode-escape')
对于Python 3,请尝试:

import os
string = "002 Could've Would've Should've"
os.system('echo ' + string)
或者尝试win unicode控制台:

pip install win-unicode-console
py -mrun your_script.py
TL;博士:

我自己在做Twitch聊天IRC机器人时遇到了这个问题。Python2.7最新版本

我想解析聊天信息以便响应

msg = s.recv(1024).decode("utf-8")
但也可以将它们以人类可读的格式安全地打印到控制台:

print(msg.encode('ascii','replace'));

这纠正了bot抛出UnicodeCodeError的问题:“charmap”错误,并将unicode字符替换为?

在执行python脚本之前,只需在命令行中输入以下代码:

chcp 65001 & set PYTHONIOENCODING=utf-8

根据模块文档,从v2.0开始,setdefaultencoding在sys中不再存在。我现在无法证明这一点,但我知道我已经在Windows上的更高版本2.5上使用了此技巧。好吧,过了一段时间,我发现:此功能仅用于站点模块实现,并且在需要时,用于sitecustomize。站点模块使用后,它将从sys模块的命名空间中删除。实际上,您可以将windows控制台设置为utf-8。你需要说chcp 65001,它将是unicode。为了明确起见:改变默认编码是一个非常糟糕的主意。这类似于把你的断腿撕成碎片,然后像什么都没发生一样继续行走,而不是让医生把骨头固定好。所有处理Unicode文本的代码都应该保持一致,而不是依赖隐式编码/解码。有没有一种方法可以通过使用不同的控制台来避免这种情况?@sorin:为什么首先在try外部导入Win32 console,然后在try内部有条件地导入?这难道不是毫无意义的第一件重要事情吗?大卫·莎拉·霍普伍德提供的那件工作我甚至没有让它运行,因为我没有费心安装win32扩展模块,也没有更改系统默认编码;改为修复Unicode值。更改默认编码可能会破坏依赖默认行为的库。在执行此操作之前,必须强制重新加载模块是有原因的。您使用的是哪一版本的Python?我看到有参考文献指出,这一点在2.4.3中被打破,在2.4.4中得到修复。相关:检查。我发现的最简单的答案是在CMD中使用pyhton之前键入:chcp 65001,然后您应该更改您接受的答案……链接已失效,并且没有引用答案的要点-1当我尝试给出的关于包装sys.stdout的建议时,它打印了错误的内容。例如,u'\u2013'变为拞而不是一个en破折号。@user2357112您将不得不发布一个关于此的新问题。Unicode和系统控制台不一定是最好的组合,但我对此了解不够,因此如果您需要明确的答案,请在此处发布一个关于它的问题。链接已失效。Windows控制台的代码示例是错误的,其中代码页OEM(如cp437)与Windows ANSI代码页(如cp1252)不同。代码未修复UnicodeEncodeError:“charmap”编解码器无法编码字符错误,并可能导致mojibake,例如,ا©被静默替换为╪º⌐..编码'utf8'。decodesys.stdout.encoding导致mojibake,例如u\N{EM DASH}。编码'utf-8'。解码'cp437'->Γcho只是打印。编码'utf-8'可能是避免编译器错误的更好方法。相反,您会得到\xNN不可打印字符的输出,这对于我的诊断消息来说已经足够了。这是非常错误的。编码为UTF-8,然后解码为8位字符集a通常会失败,并非所有的代码页都有用于所有256字节值的字符,并且b总是错误地解释数据,从而产生混乱。如果控制台使用不同的编码,例如cp437,则set-PythonionEncoding=UTF-8可能会导致错误。要将Unicode打印到Windows控制台,应使用WriteConsole中建议的Unicode API,其中PYTHONIOENCODING仅用于将当前OEM代码页中无法表示的字符替换为?WriteConsoleW甚至适用于此类角色。如果输出被重定向到文件,则可以使用PythonionEncoding。基于您的代码的Python包可以避免在脚本直接使用unicode打印时修改脚本。这是一种快速而肮脏的绕过
e问题。我认为这对于间歇式解决方案非常好。Windows上的默认控制台现在将接受所有Unicode字符,但您需要配置控制台:右键单击cmd或python IDLE窗口顶部,在默认/font中选择Lucida控制台。日语和中文对我来说都不管用,但没有它我应该活下去……@guillome:答案中包含了关于Windows控制台的粗体短语:如果配置了相应的字体。这个答案没有提到IDLE,但你不需要在其中配置字体,我看到默认情况下,IDLE中的日文和中文字符很好。请尝试打印“\u4E01”,打印“\u6b63”。@Guillaume如果在Windows 10中安装语言包,您甚至可以获得中文。它添加了支持中文的控制台字体。
msg = s.recv(1024).decode("utf-8")
print(msg.encode('ascii','replace'));
chcp 65001 & set PYTHONIOENCODING=utf-8