我有这个:
>>> print 'example'
example
>>> print 'exámple'
exámple
>>> print 'exámple'.upper()
EXáMPLE
如何打印:
EXÁMPLE
(字母 'a' 大写时如何获得重音符号。)
我正在使用 Python 2.6。
我有这个:
>>> print 'example'
example
>>> print 'exámple'
exámple
>>> print 'exámple'.upper()
EXáMPLE
如何打印:
EXÁMPLE
(字母 'a' 大写时如何获得重音符号。)
我正在使用 Python 2.6。
我认为这很简单,只需不先转换为ASCII。
>>> print u'exámple'.upper()
EXÁMPLE
在Python 2.x中,只需在调用upper()函数之前将字符串转换为Unicode即可。使用您在此网页上的UTF-8格式代码:
>>> s = 'exámple'
>>> s
'ex\xc3\xa1mple' # my terminal is not utf8. c3a1 is the UTF-8 hex for á
>>> s.decode('utf-8').upper()
u'EX\xc1MPLE' # c1 is the utf-16 aka unicode for á
调用 decode
方法将字符串从其当前格式转换为 Unicode 格式。随后,您可以使用 encode
将其转换为其他格式,比如 UTF-8。假如该字符处于 iso-8859-2 编码(例如捷克语等),则应使用 s.decode('iso-8859-2').upper()
。s.decode('utf-8').upper().encode('ascii', 'replace')
进行非严格转换,结果为 'EX?MPLE'。如果您无法使终端显示 Unicode,请将输出写入 UTF-8 格式的文件,并在您喜欢的编辑器中打开它。首先,我现在只使用 Python 3.1;它的主要优点在于将字节字符串与 unicode 对象进行了区分。这使得大多数文本操作比过去更加安全。考虑到关于 Python 2.x 编码问题的无数用户问题,Python 2.1 的 u'äbc
惯例只是一个错误;有了明确的 bytes
和 bytearray
,生活变得更加轻松。
其次,如果你不喜欢 Py3k,那么尝试使用 from __future__ import unicode_literals
,这将在 Python 2.6 和 2.7 上模仿 Py3k 的行为。这个东西将避免你在说 print 'exámple'.upper()
时犯下(容易犯的)错误。基本上,这与 Py3k 相同:print( 'exámple'.encode( 'utf-8' ).upper() )
。比较一下这些版本(对于 Py3k):
print( 'exámple'.encode( 'utf-8' ).upper() )
print( 'exámple'.encode( 'utf-8' ).upper().decode( 'utf-8' ) )
print( 'exámple'.upper() )
第一个问题,基本上是你使用裸字符串'exámple'
时所做的,前提是您将默认编码设置为utf-8
(根据BDFL的声明,在运行时设置默认编码是不好的想法,因此在py2中,您需要通过说import sys; reload(sys);sys.setdefaultencoding('utf-8')
来欺骗它;我在下面介绍了py3k的更好解决方案)。当您查看这三行代码的输出时:b'EX\xc3\xa1MPLE'
EXáMPLE
EXÁMPLE
你可以看到,当upper()
应用于第一个文本时,它作用于字节而不是字符。Python允许在字节上使用upper()
方法,但仅定义在US-ASCII解释的字节上。由于UTF-8使用值在8位之内,但在US-ASCII之外(128到255,这些未被US-ASCII使用),因此这些值不会受到upper()
的影响,所以当我们在第二行解码回来时,我们得到那个小写的á
。最后,第三行做得对,而且是的,Python似乎知道Á
是对应于á
的大写字母。我进行了快速测试,看看Python 3不转换大小写的字符有哪些:
for cid in range( 3000 ):
my_chr = chr( cid )
if my_chr == my_chr.upper() and my_chr == my_chr.lower():
say( my_chr )
浏览列表会发现很少出现拉丁文、西里尔文或希腊字母,大部分输出是非欧洲字符和标点符号。我只能找到 Python 弄错的 Ԥ/ԥ (\u0524, \u0525, '西里尔大写/小写字母带降音符 pe') 这些字符,所以只要你不使用 Latin Extended-X 块(可以查看一下,可能会有惊喜),你就可以使用这种方法。当然,我没有检查映射的正确性。
最后,在我的 Py3k 应用程序启动部分中,我添加了一个重新定义编码 sys.stdout
视图的方法,作为备选方案使用数值字符引用(NCRs),这样打印到标准输出时将永远不会引发 Unicode 编码错误。当我在 Ubuntu 上工作时,_sys.stdout.encoding
是 utf-8
;当同一程序运行在 Windows 上时,它可能是像 cp850
这样古怪的编码。输出可能看起来很奇怪,但应用程序在那些愚笨的终端上运行时不会引发异常。
#===========================================================================================================
# MAKE STDOUT BEHAVE IN A FAILSAFE MANNER
#-----------------------------------------------------------------------------------------------------------
def _harden_stdout():
"""Ensure that unprintable output to STDOUT does not cause encoding errors; use XML character references
so any kind of output gets a chance to render in a decipherable way."""
global _sys_TRM
_sys.stdout = _sys_TRM = _sys_io.TextIOWrapper(
_sys.stdout.buffer,
encoding = _sys.stdout.encoding,
errors = 'xmlcharrefreplace',
line_buffering = true )
#...........................................................................................................
_harden_stdout()
给你一个额外的建议:在测试时,始终尝试打印print repr( x )
或类似的内容,以显示x
的标识。如果您在py2中只打印x
,并且x
是八位字节字符串或unicode对象,则可能会出现各种误解。这非常令人困惑,容易引起很多烦恼。正如我所说,尝试至少使用来自未来的导入unicode文字的py26。
最后引用一句话:“Glyph Lefkowitz在他的文章Encoding中说得最好:
我相信,在这个讨论的背景下,“字符串”这个术语是毫无意义的。有文本和面向字节的数据(可以很好地表示文本,但尚未转换为文本)。在Python类型中,Text是unicode。Data是str。“非Unicode文本”的想法只是一种等待发生错误的编程错误。
更新:刚刚发现python 3正确地将ſ LATIN SMALL LETTER LONG S转换为S,当大写时。不错!
我认为我们在这里缺少一些背景:
>>> type('hello')
<type 'str'>
>>> type(u'hello')
<type 'unicode'>
试一下:
s = 'exámple'
print unicode(s).upper()