hi-ascii characters python string

时间:2015-05-21 18:29:22

标签: python string unicode utf-8

我总是对python 2.x中的整个hi-ascii处理感到困惑。我目前正面临一个问题,其中我有一个带有hiascii字符的字符串。我有几个与之相关的问题。

  1. 字符串如何在其中存储hiascii字符(不是unicode字符串,而是python 2.x中的普通str),我认为它只能处理ascii字符。 python是否在内部将hiascii转换为其他内容?

  2. 我有一个cli,我从我的python代码中生成一个子进程,当我将这个字符串传递给cli时,它运行正常。然而,如果我将此字符串编码为utf-8,则cli失败(此字符串是密码,因此无法说密码无效)。

  3. 对于第二点,我实际做了一些研究,发现了以下内容: 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,但它似乎对读取输入没有任何影响。

2 个答案:

答案 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的内容。不幸的是,长期存在的控制台错误通常会使这种方法变得不可行。

  

窗(吸入)