파이썬에서 문자열로 유니 코드를 선언하는 이유는 무엇입니까?


122

나는 여전히 파이썬을 배우고 있으며 의심이 있습니다.

파이썬 2.6.x에서는 보통 다음과 같이 파일 헤더에 인코딩을 선언합니다 ( PEP 0263 에서와 같이 ).

# -*- coding: utf-8 -*-

그 후, 내 문자열은 평소와 같이 작성됩니다.

a = "A normal string without declared Unicode"

그러나 파이썬 프로젝트 코드를 볼 때마다 인코딩이 헤더에서 선언되지 않습니다. 대신 다음과 같이 모든 문자열에서 선언됩니다.

a = u"A string with declared Unicode"

차이점이 뭐야? 이것의 목적은 무엇입니까? Python 2.6.x가 기본적으로 ASCII 인코딩을 설정한다는 것을 알고 있지만 헤더 선언으로 재정의 할 수 있으므로 문자열 선언 당 포인트는 무엇입니까?

부록 : 파일 인코딩과 문자열 인코딩을 혼합 한 것 같습니다. 설명해 주셔서 감사합니다 :)


6
# coding: utf8충분히 좋은, 필요없이입니다-*-
해파리

1
@jellyfish 나는 당신이 입력을 의미했다고 가정합니다 # coding: utf-8.
Samuel Harmer 2017

이어야 #coding=utf-8합니다. python.org/dev/peps/pep-0263
Guangtong 쉔

답변:


167

다른 사람들이 언급했듯이 그것들은 두 가지 다른 것입니다.

을 지정하면# -*- coding: utf-8 -*- 저장 한 소스 파일이 utf-8. Python 2의 기본값은 ASCII입니다 (Python 3의 경우 utf-8). 이것은 인터프리터가 파일의 문자를 읽는 방법에만 영향을줍니다.

일반적으로 인코딩이 무엇이든 상관없이 높은 유니 코드 문자를 파일에 포함하는 것은 아마도 최선의 생각이 아닙니다. 두 인코딩 모두에서 작동하는 문자열 유니 코드 이스케이프를 사용할 수 있습니다.


u 같이 앞에가 있는 문자열을 선언u'This is a string' 하면 파이썬 컴파일러에 문자열이 바이트가 아니라 유니 코드임을 알립니다. 이것은 인터프리터에 의해 대부분 투명하게 처리됩니다. 가장 명백한 차이점은 이제 문자열에 유니 코드 문자를 포함 할 수 있다는 것입니다 (즉, u'\u2665'이제 합법적 임). 를 사용 from __future__ import unicode_literals하여 기본값으로 설정할 수 있습니다 .

이것은 Python 2에만 적용됩니다. Python 3에서 기본값은 유니 코드이며 b앞에 를 지정해야합니다 (예 b'These are bytes': 바이트 시퀀스를 선언).


설명 해주셔서 감사합니다! 가장 완벽한 하나 :)이기 때문에 받아 들여 나는이를 설정합니다
오스카 Carballal

2
Python 2의 기본 소스 인코딩은 ascii 입니다.
Mark Tolonen 2010

27
실제로는 높은 유니 코드 문자를 파일에 포함하는 것이 좋습니다. 비영어권 사용자는 문자열에서 유니 코드 이스케이프를 읽고 싶어하지 않습니다.
Mark Tolonen 2010

@Mark : ASCII 수정에 감사드립니다. 저는 빠르게 PEP ( python.org/dev/peps/pep-0263 )를 훑어 보았고 서문에서 Latin-1에 대해 이야기했습니다. 대부분의 경우 파일에 높은 유니 코드 문자를 포함하는 것은 좋은 생각이 아니라고 생각합니다. 물론, 소스 파일에 영어가 아닌 문자열을 많이 코딩하는 경우 더 쉽게 만들 수 있지만 일반적으로 사용자에게 표시하기 위해이를 수행하며 어쨌든 별도의 위치에서 정의해야합니다. 그리고 하나의 잘못 구성된 텍스트 편집기는 이러한 모든 문자를 손상시킬 수 있습니다.
Chris B.

4
i18nalized 앱을 프로그래밍하는 경우 동의했지만 중국 프로그래머인지 프랑스 프로그래머인지 고려하십시오. 문자열뿐만 아니라 주석도 마찬가지입니다. Python이 소스 인코딩에 유연하다는 것은 대단합니다. Python 3은 변수 이름에 ASCII가 아닌 문자를 포함 할 수도 있습니다.
Mark Tolonen 2010

23

다른 사람들이 말했듯 # coding:이 소스 파일이 저장되는 인코딩을 지정합니다. 다음은이를 설명하는 몇 가지 예입니다.

디스크에 cp437 (내 콘솔 인코딩)로 저장되었지만 인코딩이 선언되지 않은 파일

b = 'über'
u = u'über'
print b,repr(b)
print u,repr(u)

산출:

  File "C:\ex.py", line 1
SyntaxError: Non-ASCII character '\x81' in file C:\ex.py on line 1, but no
encoding declared; see http://www.python.org/peps/pep-0263.html for details

# coding: cp437추가 된 파일의 출력 :

über '\x81ber'
über u'\xfcber'

처음에 파이썬은 인코딩을 몰랐고 비 ASCII 문자에 대해 불평했습니다. 인코딩을 알고 나면 바이트 문자열은 실제로 디스크에 있던 바이트를 얻습니다. 유니 코드 문자열의 경우 Python은 \ x81을 읽고 cp437에서 ü 라는 것을 알고 U + 00FC 인 ü 에 대한 유니 코드 코드 포인트로 디코딩했습니다 . 바이트 문자열이 인쇄 될 때 Python은 16 진수 값 81을 콘솔에 직접 보냈습니다 . 유니 코드 문자열이 인쇄 될 때, 파이썬은 제대로 CP437로 내 콘솔 인코딩을 감지 유니 코드 변환 ü를 위한 CP437 값 ü .

UTF-8로 선언되고 저장된 파일은 다음과 같습니다.

├╝ber '\xc3\xbcber'
über u'\xfcber'

UTF-8에서 ü 는 16 진수 바이트로 인코딩 C3 BC되므로 바이트 문자열에 해당 바이트가 포함되지만 유니 코드 문자열은 첫 번째 예와 동일합니다. 파이썬은 2 바이트를 읽고 올바르게 디코딩했습니다. 파이썬은 ü를 나타내는 두 개의 UTF-8 바이트 를 내 cp437 콘솔로 직접 보냈기 때문에 바이트 문자열을 잘못 인쇄했습니다 .

여기서 파일은 cp437로 선언되었지만 UTF-8로 저장됩니다.

├╝ber '\xc3\xbcber'
├╝ber u'\u251c\u255dber'

바이트 문자열은 여전히 ​​디스크에 바이트 (UTF-8 hex bytes C3 BC)를 가지고 있지만, 단일 UTF-8 인코딩 문자 대신 두 개의 cp437 문자로 해석했습니다. 유니 코드 코드 포인트로 변환 된 두 문자와 모든 것이 잘못 인쇄됩니다.


10

그것은 문자열의 형식을 설정하지 않습니다. 파일의 형식을 설정합니다. 해당 헤더를 사용하더라도 "hello"유니 코드 문자열이 아닌 바이트 문자열입니다. 유니 코드로 만들려면 u"hello"모든 곳 에서 사용해야 합니다. 헤더는 .py파일을 읽을 때 사용할 형식에 대한 힌트입니다 .


나는 착각했고, 그들은 똑같다고 생각했습니다. 그래서 유니 코드 문자열의 사용은 i18n입니까?
Oscar Carballal

@Oscar : 네, 대부분입니다. Django 등으로 웹 사이트를 만들고 비 ASCII 문자를 가진 사람들을 처리해야한다면 다른 용도로 사용할 수 있습니다.
icktoofay 2010

7

헤더 정의는 런타임에 결과 문자열이 아니라 코드 자체의 인코딩을 정의하는 것입니다.

utf-8 헤더 정의없이 파이썬 스크립트에 ۲과 같은 비 ASCII 문자를 넣으면 경고가 발생합니다

오류


-1

변수에 대한 변환을 수행 할 수 있도록 unicoder라는 다음 모듈을 만들었습니다.

import sys
import os

def ustr(string):

    string = 'u"%s"'%string

    with open('_unicoder.py', 'w') as script:

        script.write('# -*- coding: utf-8 -*-\n')
        script.write('_ustr = %s'%string)

    import _unicoder
    value = _unicoder._ustr

    del _unicoder
    del sys.modules['_unicoder']

    os.system('del _unicoder.py')
    os.system('del _unicoder.pyc')

    return value

그런 다음 프로그램에서 다음을 수행 할 수 있습니다.

# -*- coding: utf-8 -*-

from unicoder import ustr

txt = 'Hello, Unicode World'
txt = ustr(txt)

print type(txt) # <type 'unicode'>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.