Python 2.6에서 unicode_literals를 사용하는 문제가 있습니까?
우리는 이미 Python 2.6에서 실행되는 코드베이스를 얻었습니다. Python 3.0을 준비하기 위해 다음을 추가하기 시작했습니다.
__future__에서 unicode_literals 가져 오기
우리로 .py
파일 (우리가 그들을 수정으로). 나는 다른 누군가가 이것을하고 있고 분명하지 않은 문제가 발생했는지 궁금합니다 (아마도 많은 시간을 디버깅 한 후).
내가 유니 코드 문자열로 작업 한 문제의 주요 원인은 utf-8 인코딩 문자열을 유니 코드 문자열과 혼합 할 때입니다.
예를 들어 다음 스크립트를 고려하십시오.
two.py
# encoding: utf-8
name = 'helló wörld from two'
one.py
# encoding: utf-8
from __future__ import unicode_literals
import two
name = 'helló wörld from one'
print name + two.name
실행의 출력 python one.py
은 다음과 같습니다.
Traceback (most recent call last):
File "one.py", line 5, in <module>
print name + two.name
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 4: ordinal not in range(128)
이 예에서, two.name
UTF-8 인코딩 한 문자열 (유니 코드)는 가져 오지 않았기 때문에이다 unicode_literals
, 그리고 one.name
유니 코드 문자열입니다. 두 가지를 혼합하면 파이썬은 인코딩 된 문자열 (ascii라고 가정)을 디코딩하고이를 유니 코드로 변환하려고 시도하고 실패합니다. 당신이 그렇게한다면 그것은 작동 할 것 print name + two.name.decode('utf-8')
입니다.
문자열을 인코딩하고 나중에 혼합하려고하면 동일한 일이 발생할 수 있습니다. 예를 들어 다음과 같이 작동합니다.
# encoding: utf-8
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
html = html.encode('utf-8')
print 'DEBUG: %s' % html
산출:
DEBUG: <html><body>helló wörld</body></html>
그러나 추가 한 후에는 import unicode_literals
다음을 수행하지 않습니다.
# encoding: utf-8
from __future__ import unicode_literals
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
html = html.encode('utf-8')
print 'DEBUG: %s' % html
산출:
Traceback (most recent call last):
File "test.py", line 6, in <module>
print 'DEBUG: %s' % html
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 16: ordinal not in range(128)
'DEBUG: %s'
은 유니 코드 문자열 이기 때문에 실패 하므로 파이썬은 디코딩을 시도합니다 html
. 인쇄를 수정하는 몇 가지 방법은 print str('DEBUG: %s') % html
또는 print 'DEBUG: %s' % html.decode('utf-8')
.
이것이 유니 코드 문자열을 사용할 때 잠재적 인 문제를 이해하는 데 도움이되기를 바랍니다.
또한 2.6 (python 2.6.5 RC1 + 이전)에서는 유니 코드 리터럴이 키워드 인수 ( issue4978 ) 와 잘 어울리지 않습니다 .
예를 들어 다음 코드는 unicode_literals없이 작동하지만 TypeError : keywords must be string
unicode_literals가 사용되면 실패합니다 .
>>> def foo(a=None): pass
...
>>> foo(**{'a':1})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() keywords must be strings
난 당신이 추가하면 찾을 않았다 unicode_literals
지시를 당신은 또한 같은 것을 추가해야합니다 :
# -*- coding: utf-8
.py 파일의 첫 번째 또는 두 번째 줄에. 그렇지 않으면 다음과 같은 줄이 있습니다.
foo = "barré"
다음과 같은 오류가 발생합니다.
SyntaxError : 198 행의 mumble.py 파일에있는 비 ASCII 문자 '\ xc3', 그러나 인코딩이 선언되지 않았습니다. http://www.python.org/peps/pep-0263.html 참조 자세한 내용은
Also take into account that unicode_literal
will affect eval()
but not repr()
(an asymmetric behavior which imho is a bug), i.e. eval(repr(b'\xa4'))
won't be equal to b'\xa4'
(as it would with Python 3).
Ideally, the following code would be an invariant, which should always work, for all combinations of unicode_literals
and Python {2.7, 3.x} usage:
from __future__ import unicode_literals
bstr = b'\xa4'
assert eval(repr(bstr)) == bstr # fails in Python 2.7, holds in 3.1+
ustr = '\xa4'
assert eval(repr(ustr)) == ustr # holds in Python 2.7 and 3.1+
The second assertion happens to work, since repr('\xa4')
evaluates to u'\xa4'
in Python 2.7.
There are more.
There are libraries and builtins that expect strings that don't tolerate unicode.
Two examples:
builtin:
myenum = type('Enum', (), enum)
(slightly esotic) doesn't work with unicode_literals: type() expects a string.
library:
from wx.lib.pubsub import pub
pub.sendMessage("LOG MESSAGE", msg="no go for unicode literals")
doesn't work: the wx pubsub library expects a string message type.
The former is esoteric and easily fixed with
myenum = type(b'Enum', (), enum)
but the latter is devastating if your code is full of calls to pub.sendMessage() (which mine is).
Dang it, eh?!?
Click will raise unicode exceptions all over the place if any module that has from __future__ import unicode_literals
is imported where you use click.echo
. It's a nightmare…
참고URL : https://stackoverflow.com/questions/809796/any-gotchas-using-unicode-literals-in-python-2-6
'development' 카테고리의 다른 글
Faye 대 Socket.IO (및 Juggernaut) (0) | 2020.08.16 |
---|---|
C #에 CSV 리더 / 라이터 라이브러리가 있습니까? (0) | 2020.08.16 |
심볼릭 링크 :이 파일에 링크 된 모든 파일 찾기 (0) | 2020.08.16 |
어떤 디자인 패턴을 사용해야합니까? (0) | 2020.08.16 |
전체 컨텍스트로 git diff를 얻는 방법은 무엇입니까? (0) | 2020.08.16 |