Python 문자 인코딩에 대한 자세한 소개

高洛峰
풀어 주다: 2017-03-28 17:19:58
원래의
1446명이 탐색했습니다.

1. 문자 인코딩소개

1.1.ASCII

ASCII(American Standard Code for Information Interchange)는 1바이트 인코딩입니다. 처음에는 컴퓨터 세계에는 영어만 있었고 1바이트는 256개의 문자를 나타냅니다. 모두 영어 문자와 많은 제어 기호를 사용하지만 ASCII는 그 중 절반만 사용합니다(x80 이하). 이는 MBCS가 구현되는 기반이기도 합니다

그러나 곧 컴퓨터 세계에는 다른 언어가 등장했습니다. 1바이트 ASCII는 더 이상 수요를 충족할 수 없게 되었고, 나중에 1바이트로 표현할 수 있는 문자가 너무 적고 ASCII와도 호환되어야 했기 때문에 각 언어는 자체 인코딩을 개발했습니다. 인코딩이므로 이러한 인코딩은 GBxxx, BIGxxx 등과 같은 문자를 표현하기 위해 멀티바이트를 사용합니다. 첫 번째 바이트가 x80 미만이면 여전히 ASCII 문자를 나타내고 x80보다 크면 다음을 따릅니다. 다음 바이트를 합쳐서(총 2바이트) 문자를 나타내고 다음 바이트를 건너뛰고 계속해서 판단합니다.

여기서 IBM은 이를 모두 가방에 인코딩하여 할당하는 코드 페이지라는 개념을 고안했습니다. GBK는 페이지 936이며, CP936은 GBK(Multi-Byte Character

Set

)를 나타내는 데에도 사용할 수 있습니다. 따라서 MBCS는 특정 인코딩이 아니라는 점을 분명히 해야 합니다. 이는 Windows에서 사용자에 따라 설정되며 MBCS는 다른 인코딩을 참조하므로 MBCS는 사용할 수 없습니다.

Linux

의 인코딩은 Microsoft가 사람들을 놀라게 하기 위해 ANSI를 사용하기 때문에 MBCS라는 문자를 볼 수 없습니다. 메모장의 다른 이름으로 저장 대화 상자의 인코딩은 MBCS입니다. 동시에 중국어 간체 Windows의 기본 로케일 설정에서는 GBK 유니코드 나중에 누군가가 너무 많은 코드로 인해 세상이 너무 복잡해지고 머리가 아프다고 느꼈습니다. 우리는 모두 함께 모여서 브레인스토밍을 하고 방법을 생각해 냈습니다. 모든 언어의 문자는 동일한 문자 집합 으로 표시되어야 합니다. 이것이 바로 유니코드

입니다. 2에서는 문자를 표현하기 위해 2바이트를 사용하므로 유니코드가 문자를 표현하기 위해 2바이트를 사용한다는 말을 자주 들을 수 있습니다. 하지만 얼마 지나지 않아 일부 사람들은 256*256이 너무 적고 아직 부족하다고 느꼈기 때문에 4바이트를 사용하여 문자를 표현하는 UCS-4 표준이 등장했지만 우리가 가장 많이 사용하는 것은 여전히 ​​UCS-2입니다. .

UCS(Unicode Character Set)는 문자에 해당하는 코드 포인트의 표일 뿐입니다. 예를 들어 "汉"이라는 단어의 코드 포인트는 6C49입니다. UTF(UCS 변환 형식)는 특정 문자 전송 및 저장을 담당합니다. 처음에는 매우 간단합니다. UCS 코드 포인트를 사용하여 UTF-16으로 직접 저장하면 됩니다. 예를 들어 "Han"은 x6Cx49(UTF-16-BE)를 사용하여 직접 저장할 수 있습니다. 다른 방법으로는 x49x6C 저장(UTF-16-LE)입니다. 그런데 미국인들은 사용하고 나서 큰 손실을 입었다고 느낀다. 예전에는 영문자를 1바이트만 저장하면 됐는데, 이제는 큰 냄비를 먹고 나면 2바이트가 되고, 공간 소모도 두 배로 늘어난다… UTF-8 갑자기.

UTF-8은 매우 어색한 인코딩입니다. 특히, ASCII 문자는 1바이트로 표현되며 가변 길이입니다. 그런데 여기서 생략된 내용은 다른 곳에서 추출해야 합니다. UTF-8의 한자는 저장하는데 3바이트를 쓴다는 말을 들어보셨을 텐데요. 4바이트에 저장된 문자는 더욱 눈물겹다... (UCS-2가 UTF-8이 된 자세한 내용은 검색해 보세요)

또 언급할 만한 것은 BOM(Byte Order Mark)입니다. 파일을 저장할 때 파일에 사용된 인코딩이 저장되지 않는데, 열 때 저장 시 사용한 인코딩을 기억하고 이 인코딩을 사용하여 열면 문제가 많이 발생합니다. (메모장에서는 파일을 열 때 인코딩을 선택할 수 없다고 말하고 싶을 수도 있습니다. 먼저 메모장을 연 다음 파일-> 열기를 사용하여 확인하는 것이 좋습니다.) UTF는 BOM을 도입하여 자체 인코딩을 나타냅니다. 그 중 하나는 다음에 읽을 텍스트에 사용되는 인코딩이 해당 인코딩임을 의미합니다.

BOM_UTF8 'xefxbbxbf'

BOM_UTF16_LE 'xffxfe'

BOM_UTF16_BE 'xfexff'

모든

편집기

가 BOM을 작성하는 것은 아니지만 BOM이 없어도 유니코드를 읽을 수 있지만 MBCS 인코딩과 마찬가지로 특정 인코딩을 별도로 지정해야 합니다. 그렇지 않으면 디코딩이 실패합니다.

UTF-8에는 BOM이 필요하지 않다는 말을 들어보셨을 것입니다. 이는 사실이 아니지만 대부분의 편집자는 BOM이 없을 때 UTF-8을 기본 인코딩으로 읽습니다. 저장할 때 기본적으로 ANSI(MBCS)를 사용하는 메모장이라도 파일을 읽을 때 먼저 UTF-8 테스트 인코딩을 사용합니다. 성공적으로 디코딩할 수 있으면 UTF-8을 사용하여 디코딩합니다. 메모장의 이러한 어색한 접근 방식으로 인해 버그가 발생했습니다. 새 텍스트 파일을 만들고 "姹姧"를 입력한 다음 ANSI(MBCS)를 사용하여 저장하면 다시 열 때 "Han a"가 될 수도 있습니다. 시도해 보세요 :)

2. Python2.x

2.1.str 및 unicode

Str과 unicode는 모두 기본 문자열의 하위 클래스입니다. . 엄밀히 말하면 str은 실제로 유니코드로 인코딩된 바이트의 시퀀스인 바이트 문자열입니다. UTF-8로 인코딩된 str '汉'에 대해 len() 함수를 사용하면 결과는 3입니다. 실제로 UTF-8로 인코딩된 '汉' == 'xE6xB1x89'이기 때문입니다.

유니코드는 올바른 문자 인코딩과 len(u'汉') == 1을 사용하여 바이트 문자열 str을 디코딩하여 얻은 실제 string입니다.

encode()와 decode()의 두 가지 기본 문자열 인스턴스 메서드를 살펴보겠습니다. str과 유니코드의 차이점을 이해하면 이 두 메서드는 더 이상 혼동되지 않습니다.

# coding: UTF-8
 
u = u'汉'
print repr(u) # u'\u6c49'
s = u.encode('UTF-8')
print repr(s) # '\xe6\xb1\x89'
u2 = s.decode('UTF-8')
print repr(u2) # u'\u6c49'
 
# 对unicode进行解码是错误的
# s2 = u.decode('UTF-8')
# 同样,对str进行编码也是错误的
# u2 = s.encode('UTF-8')
로그인 후 복사

str에서 encode() 메서드를 호출하는 것은 잘못되었지만 실제로 Python은 예외를 발생시키지 않고 내용은 동일하지만 유니코드에서 decode를 호출하는 ID가 다른 다른 str을 반환합니다. () 메서드도 마찬가지입니다. encode()와 decode()가 각각 unicode와 str에 배치되지 않고 둘 다 basestring에 배치되는 이유를 정말로 이해하지 못합니다. 하지만 이런 경우이므로 실수하지 않도록 주의합시다.

2.2. 문자 인코딩 선언

소스 코드 파일에 ASCII가 아닌 문자를 사용하는 경우 파일 헤더에 다음과 같이 문자 인코딩 선언을 해야 합니다.

#-*- coding: UTF-8 -*-
로그인 후 복사

사실 파이썬은 #, 코딩, 인코딩 문자열만 확인하고, 미적인 측면을 위해 다른 문자들이 추가됩니다. 또한 Python에는 다양한 문자 인코딩이 있으며 대소문자를 구분하지 않는 별칭도 많이 있습니다. 예를 들어 UTF-8은 u8로 쓸 수 있습니다. http://docs.python.org/library/codecs.html#standard-encodings를 참조하세요.

또 한 가지 주의할 점은 선언된 인코딩이 파일이 실제로 저장될 때 사용된 인코딩과 일치해야 한다는 것입니다. 그렇지 않으면 코드 구문 분석 예외가 발생할 가능성이 높습니다. 오늘날의 IDE는 일반적으로 선언을 변경한 후 선언된 인코딩에 저장되지만 텍스트 편집기 컨트롤은 주의가 필요합니다.)

2.3 파일 읽기 및 쓰기

내장 open() 메소드가 파일을 열 때 read()는 str을 읽습니다. 읽은 후에는 올바른 인코딩 형식을 사용하여 decode()해야 합니다. () 작성 시 매개변수가 유니코드인 경우 encode()에 작성하려는 인코딩을 사용해야 하며, 다른 인코딩 형식의 str인 경우 먼저 해당 str의 인코딩을 사용하여 decode()해야 합니다. 그런 다음 작성된 인코딩을 사용하여 encode()합니다. 유니코드를 write() 메서드에 매개 변수로 직접 전달하면 Python은 먼저 소스 코드 파일에 선언된 문자 인코딩을 사용하여 인코딩한 다음 씁니다.

# coding: UTF-8
 
f = open('test.txt')
s = f.read()
f.close()
print type(s) # <type &#39;str&#39;>
# 已知是GBK编码,解码成unicode
u = s.decode('GBK')
 
f = open('test.txt', 'w')
# 编码成UTF-8编码的str
s = u.encode('UTF-8')
f.write(s)
f.close()
로그인 후 복사

또한 모듈 코덱은 파일을 열기 위한 인코딩을 지정할 수 있는 open() 메서드를 제공합니다. 이 메서드를 사용하여 연 파일은 유니코드를 읽고 반환합니다. 쓰기 시 매개변수가 유니코드인 경우 open() 중에 지정된 인코딩을 사용하여 인코딩되고, str인 경우에는 수행하기 전에 소스 코드 파일에 선언된 문자 인코딩에 따라 유니코드로 디코딩됩니다. 앞서 언급한 수술. 내장된 open()과 비교하여 이 방법은 코딩 문제가 발생할 가능성이 적습니다.

# coding: GBK
 
import codecs
 
f = codecs.open('test.txt', encoding='UTF-8')
u = f.read()
f.close()
print type(u) # <type &#39;unicode&#39;>
 
f = codecs.open('test.txt', 'a', encoding='UTF-8')
# 写入unicode
f.write(u)
 
# 写入str,自动进行解码编码操作
# GBK编码的str
s = '汉'
print repr(s) # '\xba\xba'
# 这里会先将GBK编码的str解码为unicode再编码为UTF-8写入
f.write(s)
f.close()
로그인 후 복사

2.4.인코딩 관련 방법

sys/locale 모듈은 현재 환경에서 기본 인코딩을 얻기 위한 몇 가지 방법을 제공합니다.

# coding:gbk
 
import sys
import locale
 
def p(f):
    print '%s.%s(): %s' % (f.module, f.name, f())
 
# 返回当前系统所使用的默认字符编码
p(sys.getdefaultencoding)
 
# 返回用于转换Unicode文件名至系统文件名所使用的编码
p(sys.getfilesystemencoding)
 
# 获取默认的区域设置并返回元祖(语言, 编码)
p(locale.getdefaultlocale)
 
# 返回用户设定的文本数据编码
# 文档提到this function only returns a guess
p(locale.getpreferredencoding)
 
# \xba\xba是'汉'的GBK编码
# mbcs是不推荐使用的编码,这里仅作测试表明为什么不应该用
print r"'\xba\xba'.decode('mbcs'):", repr('\xba\xba'.decode('mbcs'))
 
#在笔者的Windows上的结果(区域设置为中文(简体, 中国))
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp936')
#locale.getpreferredencoding(): cp936
#'\xba\xba'.decode('mbcs'): u'\u6c49'
로그인 후 복사

3. 몇 가지 제안

3.1. 문자 인코딩 선언을 사용하고, 동일한 프로젝트의 모든 소스 코드 파일은 동일한 문자 인코딩 선언을 사용합니다.

반드시 해야 할 일입니다.

3.2. str을 버리고 모두 유니코드를 사용하세요.

따옴표를 누르기 전에 u를 누르는 것이 처음에는 익숙해지기 어렵고, 돌아가서 고치는 것을 잊어버리는 경우가 많지만, 이렇게 하면 90%를 줄일 수 있습니다. 코딩 문제. 인코딩 문제가 심각하지 않다면 이 글을 참고하실 필요는 없습니다.

3.3. 내장된 open() 대신 codecs.open()을 사용하세요.

인코딩 문제가 심각하지 않다면 이 글을 참고하지 않으셔도 됩니다.

3.4 반드시 피해야 할 문자 인코딩: MBCS/DBCS 및 UTF-16.

여기서 언급된 MBCS는 GBK나 다른 것을 사용할 수 없다는 의미가 아니라 프로그램이 이식성이 전혀 없는 경우가 아니면 Python에서 'MBCS'라는 인코딩을 사용해서는 안된다는 의미입니다.

파이썬의 'MBCS'와 'DBCS' 인코딩은 동의어로, 현재 Windows 환경에서 MBCS가 참조하는 인코딩을 말합니다. Python의 Linux 구현에는 이러한 인코딩이 없으므로 Linux로 이식되면 예외가 확실히 발생합니다! 또한 Windows 시스템 지역 집합이 다른 한 MBCS에서 참조하는 인코딩도 다릅니다. 다양한 영역을 설정하고 섹션 2.4의 코드를 실행한 결과:

#中文(简体, 中国)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp936')
#locale.getpreferredencoding(): cp936
#'\xba\xba'.decode('mbcs'): u'\u6c49'
 
#英语(美国)
#sys.getdefaultencoding(): UTF-8
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\xba\xba'.decode('mbcs'): u'\xba\xba'
 
#德语(德国)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\xba\xba'.decode('mbcs'): u'\xba\xba'
 
#日语(日本)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp932')
#locale.getpreferredencoding(): cp932
#'\xba\xba'.decode('mbcs'): u'\uff7a\uff7a'
로그인 후 복사

可见,更改区域后,使用mbcs解码得到了不正确的结果,所以,当我们需要使用'GBK'时,应该直接写'GBK',不要写成'MBCS'。

UTF-16同理,虽然绝大多数操作系统中'UTF-16'是'UTF-16-LE'的同义词,但直接写'UTF-16-LE'只是多写3个字符而已,而万一某个操作系统中'UTF-16'变成了'UTF-16-BE'的同义词,就会有错误的结果。实际上,UTF-16用的相当少,但用到的时候还是需要注意。

위 내용은 Python 문자 인코딩에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿