我总是对python 2.x中的整个hi-ascii处理感到困惑。我目前正面临一个问题,其中我有一个带有hiascii字符的字符串。我有几个与之相关的问题。
字符串如何在其中存储hiascii字符(不是unicode字符串,而是python 2.x中的普通str),我认为它只能处理ascii字符。 python是否在内部将hiascii转换为其他内容?
我有一个cli,我从我的python代码中生成一个子进程,当我将这个字符串传递给cli时,它运行正常。然而,如果我将此字符串编码为utf-8,则cli失败(此字符串是密码,因此无法说密码无效)。
对于第二点,我实际做了一些研究,发现了以下内容: 1)在windows(sucks)中,命令行args以mbcs(sys.getfilesystemencoding)编码。我还没有得到的问题是,如果我使用raw_input读取相同的字符串,则使用Windows控制台编码进行编码(在EN窗口中,它是cp437)。
我有一个不同的问题,现在对于Windows编码感到困惑。 Windows sys.stdin.encoding是否与Windows控制台编码不同? 如果是的话,是否有一种pythonic方法来确定我的Windows控制台编码是什么。我需要这个,因为当我使用raw_input读取输入时,它在Windows控制台编码中编码,我想将其转换为utf-8。注意:我已经将我的sys.stdin.encoding设置为utf-8,但它似乎对读取输入没有任何影响。
答案 0 :(得分:0)
要回答第一个问题,Python 2.x字节字符串包含字符的源编码字节,这意味着用于在源文件中将字符串存储在磁盘上的确切字节。例如,这是一个Python 2.x程序,其中源以Windows-1252
编码保存(记事本在美国Windows上的默认值):
#!python2
#coding:windows-1252
s = 'æüÿ€éêè'
u = u'æüÿ€éêè'
print repr(s)
print repr(u)
输出:
'\xe6\xfc\xff\x80\xe9\xea\xe8'
u'\xe6\xfc\xff\u20ac\xe9\xea\xe8'
字节字符串包含表示Windows-1252中字符的字节。
Python将使用声明的源编码(!#coding:Windows-1252
)的相同序列解码为Unicode代码点。由于Windows-1252
非常接近iso-8859-1,并且iso-8859-1
是与前0-255个Unicode代码点的1:1映射,因此除欧元字符外,代码点几乎相同
但是以不同的编码保存源代码,您将获得字节字符串的那些字节:
#!python2
#coding:utf8
s = 'æüÿ€éêè'
u = u'æüÿ€éêè'
print repr(s)
print repr(u)
输出:
'\xc3\xa6\xc3\xbc\xc3\xbf\xe2\x82\xac\xc3\xa9\xc3\xaa\xc3\xa8'
u'\xe6\xfc\xff\u20ac\xe9\xea\xe8'
因此,Python 2.X只是直接为您提供源代码字节,而不是将它们解码为Unicode代码点,就像Unicode字符串一样。
Python 3.X指出这很令人困惑,只是禁止字节字符串中的非ASCII字符:
#!python3
#coding:utf8
s = b'æüÿ€éêè'
u = 'æüÿ€éêè'
print(repr(s))
print(repr(u))
输出:
File "C:\test.py", line 3
s = b'æüÿ\u20acéêè'
^
SyntaxError: bytes can only contain ASCII literal characters.
要回答您的第二个问题,请编辑您的问题以显示演示此问题的示例。
答案 1 :(得分:0)
windows sys.stdin.encoding是否与Windows控制台编码不同?
是。有两个特定于语言环境的代码页:
ANSI代码页,又名mbcs
,用于Win32 ...A
API中的字符串,因此用于C运行时操作,例如读取命令行;
IO代码页,用于stdin / stdout / stderr流。
这些不必是相同的编码,通常它们不是。在我的语言环境(英国)中,ANSI代码页是1252,IO代码页默认为850.您可以使用chcp
命令更改控制台代码页,这样您就可以使用例如{{{}}匹配两个编码1}}在运行Python命令之前。
(您还必须在chcp 1252
的控制台中使用TrueType字体才能有所作为。)
是否有一种pythonic方式来确定我的Windows控制台编码是什么。
Python在启动时使用Win32 API chcp
读取它,除非被GetConsoleOutputCP
覆盖,否则将其写入属性PYTHONIOENCODING
。 (同样sys.stdout.encoding
代表GetConsoleCP
,但它们通常是相同的代码页。)
如果您需要直接阅读此内容,无论是否设置了stdin
,您可能必须使用ctypes直接调用PYTHONIOENCODING
。
注意:我已经将我的sys.stdin.encoding设置为utf-8,但它似乎没有对读取输入产生任何影响。
(你是怎么做到的?它是一个只读属性。)
虽然您可以在最后将输入和输出视为UTF-8,但Windows控制台不会以该编码提供或显示内容。您通过命令行调用的大多数其他工具也将在IO代码页中对其输入进行编码,因此会误解为发送给它们的任何UTF-8。
您可以通过使用ctypes调用Win32 GetConsoleOutputCP
/ SetConsoleCP
API(相当于SetConsoleOutputCP
命令并且还需要TTF控制台字体)来影响控制台端使用的代码页。原则上,您应该能够设置代码页65001并获得几乎为UTF-8的内容。不幸的是,长期存在的控制台错误通常会使这种方法变得不可行。
窗(吸入)
是