Kim*_*ais 9 python printing unicode python-2.x
我正在看这个问题,并开始想知道print
实际上做了什么.
我从来没有发现如何使用string.decode()
和string.encode()
在python交互式shell中以与打印相同的格式获取unicode字符串"out".无论我做什么,我都会得到
这是python 2.x,但我已经尝试修改我的方式并实际调用print()
:)
例:
>>> import sys
>>> a = '\xAA\xBB\xCC'
>>> print(a)
ª»Ì
>>> a.encode(sys.stdout.encoding)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0xaa in position 0: ordinal not in range(128)
>>> a.decode(sys.stdout.encoding)
u'\xaa\xbb\xcc'
Run Code Online (Sandbox Code Playgroud)
编辑:
我为什么这么问?我厌倦了encode()
错误,并意识到,因为print
可以做到(至少在交互式shell中).我知道一定有办法神奇地做编码PROPERLY,通过下挖信息从什么地方用什么编码?
附加信息:我在linux2上运行Python 2.4.3(#1,2009年9月3日,15:37:12)[GCC 4.1.2 20080704(Red Hat 4.1.2-46)]
>>> sys.stdin.encoding
'ISO-8859-1'
>>> sys.stdout.encoding
'ISO-8859-1'
Run Code Online (Sandbox Code Playgroud)
但是,在同一个Linux机器上的结果与Python 2.6.2(r262:71600,2009年9月8日,13:06:43)相同.
编辑:(此编辑与前一个编辑之间的重大更改...注意:我在Ubuntu框中使用Python 2.6.4.)
首先,我在回答第一个尝试,我所提供的一般信息,print
而且str
这我要去下面要离开有任何简单的问题与利益print
,并就这个问题chancing.至于处理OP遇到的问题的新尝试......基本上,我倾向于说这里没有银弹,如果print
以某种方式设法理解一个奇怪的字符串文字,那么这不是可重现的行为.我在终端窗口中通过以下与Python的有趣交互得出了这个结论:
>>> print '\xaa\xbb\xcc'
??
Run Code Online (Sandbox Code Playgroud)
您是否尝试直接从终端输入ª»Ì?在使用utf-8作为编码的Linux终端上,这实际上是以六个字节读入的,然后可以借助该decode
方法使其看起来像三个unicode字符:
>>> 'ª»Ì'
'\xc2\xaa\xc2\xbb\xc3\x8c'
>>> 'ª»Ì'.decode(sys.stdin.encoding)
u'\xaa\xbb\xcc'
Run Code Online (Sandbox Code Playgroud)
因此,'\xaa\xbb\xcc'
如果您将其解码为latin-1文字,那么文字才有意义(实际上,您可以使用与相关字符上的latin-1一致的不同编码).至于print
你的情况下"正常工作",它肯定不适合我 - 如上所述.
这是因为当您使用不带前缀的字符串文字时u
- "asdf"
而不是u"asdf"
- 结果字符串将使用一些非unicode编码.没有; 事实上,字符串对象本身将是编码 - 不知道,并且您将不得不将其视为使用编码x进行编码,以获得正确的x值.这个基本想法让我得到以下结论:
a = '\xAA\xBB\xCC'
a.decode('latin1')
# result: u'\xAA\xBB\xCC'
print(a.decode('latin1'))
# output: ª»Ì
Run Code Online (Sandbox Code Playgroud)
注意缺少解码错误和正确的输出(我希望在任何其他方框保持正确).显然你的字符串文字可以通过Python理解,但不是没有一些帮助.
这有帮助吗?(至少在了解事情是如何工作的情况下,如果不是更容易处理编码......)
现在为一些有趣的位有一些解释价值(希望)!这对我来说很好:
sys.stdout.write("\xAA\xBB\xCC".decode('latin1').encode(sys.stdout.encoding))
Run Code Online (Sandbox Code Playgroud)
跳过解码或编码部分会导致与unicode相关的异常.从理论上讲,这是有道理的,因为需要第一个解码来决定给定字符串中的字符(第一眼看到的唯一明显的是字节是什么- Python 3为字符设置(unicode)字符串的想法和字节,以及字节,突然看起来非常合理),而需要编码,以便输出尊重输出流的编码.现在这个
sys.stdout.write("?öî\n".decode(sys.stdin.encoding).encode(sys.stdout.encoding))
Run Code Online (Sandbox Code Playgroud)
也按预期工作,但字符实际上来自键盘,因此实际上使用stdin编码编码...此外,
ord('?'.decode('utf-8').encode('latin2'))
Run Code Online (Sandbox Code Playgroud)
返回正确的177(我的输入编码是utf-8),但'\ xc4\x85'.encode('latin2')对Python没有任何意义,因为它不知道如何理解'\ xc4\x85'和数字,尝试'ascii'代码是它能做的最好的.
原答案:
Python文档的相关部分(对于版本2.6.4)说这print(obj)
意味着打印出给出的字符串str(obj)
.我想你可以将它包装在一个调用unicode
(如unicode(str(obj))
)中以获取一个unicode字符串 - 或者你可以只使用Python 3并将这种特殊的麻烦交换给几个不同的字符串.;-)
顺便说一下,这表明您可以操纵print
对象的结果,就像您可以操纵调用str
对象的结果一样,即通过弄乱__str__
方法.例:
class Foo(object):
def __str__(self):
return "I'm a Foo!"
print Foo()
Run Code Online (Sandbox Code Playgroud)
至于实际的实现print
,我希望这根本不会有用,但如果你真的想知道发生了什么......它Python/bltinmodule.c
在Python源文件中(我正在看2.6.4版本) .搜索以builtin_print
.开头的行.它实际上完全是直截了当的,没有任何魔力在那里.:-)
希望这能回答你的问题...但如果你确实有一个我完全错过的更为神秘的问题,请做评论,我会再做一次.另外,我假设我们正在处理Python 2.x; 否则我想我不会有一个有用的评论.
print()
用于sys.stdout.encoding
确定输出控制台可以理解的内容,然后在调用中使用此编码str.encode()
.
[编辑]如果您查看源代码,它会获取sys.stdout
然后调用:
PyFile_WriteObject(PyTuple_GetItem(args, i), file,
Py_PRINT_RAW);
Run Code Online (Sandbox Code Playgroud)
我想魔法已经存在,Py_PRINT_RAW
但消息来源只是说:
if (flags & Py_PRINT_RAW) {
value = PyObject_Str(v);
}
Run Code Online (Sandbox Code Playgroud)
所以这里没有魔力.对参数的循环sys.stdout.write(str(item))
应该可以解决问题.
归档时间: |
|
查看次数: |
13541 次 |
最近记录: |