이번 포스팅에서는 데이터 길들이기 위한 여러 가지 기술에 대해 알아봅니다. 이들 대부분은 다음과 같은 내장 파이썬 데이터 유형에 관한 것이다.
줄들
텍스트 데이터에 사용되는 유니코드 문자 시퀀스.
바이트와 바이패스
이진 데이터에 사용되는 8비트 정수 시퀀스입니다.
텍스트 문자열
텍스트는 대부분의 독자들에게 가장 익숙한 데이터 유형입니다. 따라서 파이썬에서 텍스트 문자열의 강력한 기능 중 몇 가지를 살펴보겠습니다.
유니코드
지금까지 이 책의 모든 텍스트 예제는 평범한 옛 아스키이다. ASCII는 1960년대에 정의되었는데, 그 당시 컴퓨터는 냉장고 크기였고 계산을 조금 더 잘했다. 컴퓨터 저장의 기본 단위는 바이트이며, 바이트는 8비트에 256개의 고유값을 저장할 수 있다. 여러 가지 이유로 ASCII는 대문자 26개, 소문자 26개, 숫자 10개, 일부 펑크음 기호, 일부 띄어쓰기 문자 및 일부 비인쇄 제어 코드 등 7비트(128개의 고유 값)만 사용했습니다.
불행하게도, 세계는 ASCII가 제공하는 것보다 더 많은 글자를 가지고 있다. 당신은 식당에서 핫도그를 먹을 수 있지만, 카페에서는 절대로 게뷔르츠트라미네르1을 먹지 않는다. 더 많은 문자와 기호를 추가하기 위한 많은 시도가 있었고, 여러분은 때때로 그것들을 볼 수 있을 것입니다. 그 중 몇 가지 예를 들 수 있습니다.
1. 이 와인은 독일에 음라우트가 있는데 프랑스에서는 잃어버려요.
• Latin-1, or ISO 8859-1
• Windows code page 1252
이들 각각은 8비트를 모두 사용합니다. 하지만 그것조차도 충분하지 않습니다. 특히 비유럽 언어가 필요할 때는요. 유니코드는 수학과 다른 분야의 기호와 더불어 세계 모든 언어의 문자를 정의하는 지속적인 국제 표준이다.
유니코드는 플랫폼, 프로그램, 언어와 상관없이 모든 문자에 대해 고유한 번호를 제공합니다.
유니코드 코드 차트 페이지에는 이미지가 있는 현재 정의된 모든 문자 집합에 대한 링크가 있습니다. 최신 버전(6.2)에서는 각각 고유한 이름과 식별 번호를 가진 110,000자 이상의 문자를 정의합니다. 문자는 평면이라고 하는 8비트 집합으로 나뉩니다. 처음 256면은 기본 다국어 평면이다. 자세한 내용은 유니코드 평면에 대한 위키피디아 페이지를 참조하십시오.
파이썬 3 유니코드 문자열
Python 3 문자열은 바이트 배열이 아닌 유니코드 문자열입니다. 이는 일반 바이트 문자열과 유니코드 문자 문자열을 구분하는 파이썬 2와 비교할 때 가장 큰 변화입니다.
유니코드 ID 또는 문자 이름을 알고 있는 경우 파이썬 문자열에서 사용할 수 있습니다. 다음은 몇 가지 예입니다.
• \u 다음에 4개의 16진수2는 유니코드의 256개의 기본 다국어 평면 중 하나에 있는 문자를 지정합니다. 처음 두 개는 평면 번호(00에서 FF)이고 다음 두 개는 평면 내 문자 색인입니다. 평면 00은 오래된 ASCII이며, 평면 내의 문자 위치는 ASCII와 동일합니다.
• 고차원 문자의 경우 비트가 더 필요합니다. Python 이스케이프 시퀀스는 \U 다음에 8개의 16진수 문자가 나옵니다. 가장 왼쪽 문자는 0이어야 합니다.
• 모든 문자에 대해 \N{ 이름 }을(를) 사용하여 표준 이름으로 지정할 수 있습니다. 유니코드 문자 이름 색인 페이지에는 이러한 항목이 나열됩니다.
파이썬 유니코드다 모듈에는 양방향으로 변환하는 기능이 있습니다.
• 검색—대소문자를 구분하지 않는 이름을 사용하고 유니코드 문자를 반환합니다.
• 이름 표시—유니코드 문자를 사용하고 대문자 이름을 반환합니다.
다음 예에서는 Python Unicode char act acter를 사용하여 이름을 조회한 다음 이름(원래 문자와 일치해야 함)에서 문자를 다시 검색하는 테스트 함수를 작성하겠습니다.
>>> def unicode_test(value):
- ... import unicodedata
- ... name = unicodedata.name(value)
- ... value2 = unicodedata.lookup(name)
- ... print('value="%s", name="%s", value2="%s"' % (value, name, value2)) ...
일반 ASCII 문자로 시작하는 몇 가지 문자를 사용해 보겠습니다.
- >>> unicode_test('A')
- value="A", name="LATIN CAPITAL LETTER A", value2="A"
ASCII punctuation:
>>> unicode_test('$')- value="$", name="DOLLAR SIGN", value2="$"
A Unicode currency character:
>>> unicode_test('\u00a2')
value="¢", name="CENT SIGN", value2="¢"
Another Unicode currency character:
>>> unicode_test('\u20ac')
value="€", name="EURO SIGN", value2="€"
잠재적으로 발생할 수 있는 유일한 문제는 텍스트를 표시하는 데 사용하는 글꼴의 제한입니다. 모든 글꼴에 모든 유니코드 문자에 대한 이미지가 없는 경우 일부 자리 표시자 문자가 표시될 수 있습니다. 예를 들어, 딩뱃 글꼴의 기호와 같은 스노우맨의 유니코드 기호는 다음과 같습니다.
- >>> unicode_test('\u2603')
value="☃", name="SNOWMAN", value2="☃"
카페라는 단어를 파이썬 문자열에 저장하려고 합니다. 한 가지 방법은 파일이나 웹 사이트에서 복사하여 붙여넣기하여 다음 작업을 수행하는 것입니다.
- >>> place = 'café'
- >>> place
- 'café'
UTF-8 인코딩을 사용한 원본에서 텍스트에 복사하여 붙여넣었기 때문에 가능했습니다.
최종문자를 어떻게 지정할 수 있습니까? E의 문자 색인을 보면, 급성 라틴 소문자 이름 E의 값이 00E9임을 알 수 있습니다. 방금 사용하던 이름() 및 조회() 함수로 확인해 보겠습니다. 먼저 코드를 입력하여 이름을 가져옵니다.
>>> unicodedata.name('\u00e9') 'LATIN SMALL LETTER E WITH ACUTE'
그런 다음 코드를 조회할 이름을 지정합니다.
>>> unicodedata.lookup('E WITH ACUTE, LATIN SMALL LETTER')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: "undefined character name 'E WITH ACUTE, LATIN SMALL LETTER'"
유니코드 문자 이름 색인 페이지에 나열된 이름은 표시에 적합하게 정렬되도록 다시 포맷되었습니다. 이러한 이름을 실제 유니코드 이름(파이썬에서 사용하는 이름)으로 변환하려면 쉼표를 제거하고 쉼표 뒤에 있던 이름의 일부를 처음으로 이동합니다. 따라서 급성 라틴 소문자 E를 급성 라틴 소문자 E로 변경합니다.
>>> unicodedata.lookup('LATIN SMALL LETTER E WITH ACUTE') 'é'
이제 코드 또는 이름으로 문자열 카페를 지정할 수 있습니다.
>>> place = 'caf\u00e9'
>>> place
'café'
>>> place = 'caf\N{LATIN SMALL LETTER E WITH ACUTE}' >>> place
'café'
앞의 코드 조각에서 문자열에 직접 é를 삽입했지만 다음을 추가하여 문자열을 만들 수도 있습니다.
>>> u_umlaut = '\N{LATIN SMALL LETTER U WITH DIAERESIS}' >>> u_umlaut
'ü'
>>> drink = 'Gew' + u_umlaut + 'rztraminer'
>>> print('Now I can finally have my', drink, 'in a', place) Now I can finally have my Gewürztraminer in a café
문자열 렌 함수는 바이트가 아닌 유니코드 문자를 카운트합니다.
>>> len('$')
1
>>> len('\U0001f47b') 1
Encode and decode with UTF-8
일반적인 문자열을 처리할 때 파이썬에서 각 유니코드 문자를 저장하는 방법에 대해 걱정할 필요가 없습니다.
그러나 외부와 데이터를 교환할 때는 두 가지 사항이 필요합니다.
문자 문자열을 바이트로 인코딩하는 방법
문자 문자열로 바이트를 디코딩하는 방법
유니코드에 64,000자 미만의 문자가 있으면 각 유니코드 문자 ID를 2바이트로 저장할 수 있습니다. 불행하게도, 더 있습니다. 각 ID를 3, 4바이트 단위로 인코딩할 수 있지만, 그렇게 하면 공통 텍스트 문자열에 대한 메모리 및 디스크 저장 공간이 3, 4배 증가합니다.
Unix 개발자들에게 친숙한 이름을 가진 Ken Thompson과 Rob Pike는 어느 날 밤 뉴저지의 한 식당에서 UTF-8 동적 인코딩 방식에 서명했다. 유니코드 문자당 1~4바이트를 사용합니다.
• ASC용 1바이트Ⅱ
• 대부분의 라틴어에서 파생된 언어(키릴어는 아님)의 경우 2바이트
• 나머지 다국어 평면의 경우 3바이트
• 일부 아시아 언어와 기호를 포함한 나머지 4바이트
UTF-8은 Python, Linux 및 HTML의 표준 텍스트 인코딩입니다. 빠르고 완전하며 잘 작동합니다. 만약 당신이 코드 전체에 UTF-8 인코딩을 사용한다면, 삶은 다양한 인코딩에 들어가고 나오는 것보다 훨씬 쉬울 것이다.
웹 페이지와 같은 다른 원본에서 복사하여 붙여넣기하여 파이썬 문자열을 만드는 경우, 소스가 UTF-8 형식으로 인코딩되어 있는지 확인하십시오. Latin-1 또는 Windows 1252로 인코딩된 텍스트가 파이썬 문자열로 복사되어 나중에 잘못된 바이트 시퀀스로 돌출되는 것을 볼 수 있습니다.
- Encoding
- 문자열을 바이트로 인코딩합니다. 문자열 인코딩() 함수의 첫 번째 인수는 en coding 부호화 이름입니다. 선택사항은 표 7-1에 제시된 것을 포함한다.
- Table 7-1. Encodings
- 'ascii' Good old seven-bit ASCII
'utf-8' Eight-bit variable-length encoding, and what you almost always want to use - 'latin-1' Also known as ISO 8859-1
'cp-1252' A common Windows encoding - 'unicode-escape' Python Unicode literal format,\uxxxx or\Uxxxxxxxx
- UTF-8로 인코딩할 수 있습니다. 유니코드 문자열 '\u2603'을 스노우맨 이름에 할당해 보겠습니다.
>>> snowman = '\u2603'
스노우맨은 내부적으로 저장하는 데 필요한 바이트 수에 관계없이 단일 문자를 가진 파이썬 유니코드 문자열입니다.
>>> len(snowman)
1
다음으로 이 유니코드 문자를 바이트 순서로 인코딩해 보겠습니다.
>>> ds = snowman.encode('utf-8')
앞서 언급했듯이 UTF-8은 가변 길이 인코딩입니다. 이 경우, 3개를 사용했습니다.
단일 눈사람 유니코드 문자를 인코딩하는 바이트:
>>> len(ds)
3
>>> ds b'\xe2\x98\x83'
이제 len()은 ds가 바이트 변수이기 때문에 바이트 수를 반환합니다.
UTF-8 이외의 인코딩을 사용할 수 있지만 인코딩으로 유니코드 문자열을 처리할 수 없는 경우 오류가 발생합니다. 예를 들어, ASCII 인코딩을 사용하는 경우 유니코드 문자도 유효한 ASCII 문자가 아니면 실패합니다.
>>> ds = snowman.encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u2603' in position 0: ordinal not in range(128)
인코딩() 함수는 인코딩 예외를 방지하는 데 도움이 되는 두 번째 인수를 사용합니다. 이전 예에서 볼 수 있는 기본값은 '엄격'입니다. ASC가 아닌 경우 유니코드EncodeError가 발생합니다.II 캐릭터. 다른 인코딩도 있습니다. 인코딩되지 않는 것을 버리려면 '무시'를 사용하십시오.
>>> snowman.encode('ascii', 'ignore')
b''
알 수 없는 문자를 대체하려면 '바꾸기'를 사용하십시오.
>>> snowman.encode('ascii', 'replace')
b'?'
유니코드와 같은 파이썬 유니코드 문자 문자열을 만들려면 '백슬래시 바꾸기'를 사용하십시오.
escape:
>>> snowman.encode('ascii', 'backslashreplace')
b'\\u2603'
유니코드 이스케이프 시퀀스의 인쇄 가능한 버전이 필요한 경우 이 옵션을 사용합니다. 다음은 웹 페이지에서 사용할 수 있는 문자 엔터티 문자열을 생성합니다.
>>> snowman.encode('ascii', 'xmlcharrefreplace')
b'☃'
디코딩
바이트 문자열을 유니코드 문자열로 디코딩합니다. 일부 외부 소스(파일, 데이터베이스, 웹 사이트, 네트워크 API 등)에서 텍스트를 가져올 때마다 바이트 문자열로 인코딩됩니다. 까다로운 부분은 어떤 인코딩이 실제로 사용되었는지 알기 때문에 이를 역방향으로 실행하고 유니코드 문자열을 가져올 수 있습니다.
문제는 바이트 문자열 자체에 사용된 인코딩을 나타내는 것은 없다는 것이다. 나는 앞서 웹사이트에서 복사와 붙여넣기의 위험에 대해 언급했다. 여러분은 아마도 보통 오래된 ASCII 문자가 있어야 하는 홀수 문자로 웹사이트를 방문한 적이 있을 것이다.
'카페' 값을 사용하여 플레이스라는 유니코드 문자열을 만듭니다.
>>> place = 'caf\u00e9' >>> place
'café'
>>> type(place)
<class 'str'>
place_bytes라는 바이트 변수로 UTF-8 형식으로 인코딩합니다.
>>> place_bytes = place.encode('utf-8') >>> place_bytes
b'caf\xc3\xa9'
>>> type(place_bytes)
<class 'bytes'>
place_bytes는 5바이트입니다. 처음 3개는 ASCII (UTF-8의 강도)와 동일하며, 마지막 2개는 'é'를 인코딩한다. 이제 바이트 문자열을 유니코드 문자열로 다시 디코딩해 보겠습니다.
>>> place2 = place_bytes.decode('utf-8')
>>> place2
'café'
UTF-8로 인코딩하고 UTF-8로 디코딩했기 때문에 가능했습니다. 다른 인코딩에서 디코딩하라고 하면 어떨까요?
>>> place3 = place_bytes.decode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128)
바이트 값 0xc3이 ASCII에서 잘못되었기 때문에 ASCII 디코더가 예외를 발생시켰습니다. 128 (헥스 80)과 255 (헥스 FF) 사이의 값이 UTF-8과 동일하지는 않지만 합법적인 일부 8비트 문자 집합 인코딩이 있습니다.
>>> place4 = place_bytes.decode('latin-1')
>>> place4
'café'
>>> place5 = place_bytes.decode('windows-1252')
>>> place5
'café'
Urk.
이 이야기의 교훈은 가능할 때마다 UTF-8 인코딩을 사용하라는 것이다. 모든 곳에서 작동하고 지원되며 모든 유니코드 문자를 표현할 수 있으며 빠르게 디코딩되고 인코딩됩니다.
이 이야기의 교훈은 가능할 때마다 UTF-8 인코딩을 사용하라는 것이다. 모든 곳에서 작동하고 지원되며 모든 유니코드 문자를 표현할 수 있으며 빠르게 디코딩되고 인코딩됩니다.
자세한 정보는
자세한 내용은 다음 링크를 참조하십시오.
• 유니코드 HOWTO
• 실용 유니코드
• 모든 소프트웨어 개발자가 유니코드 및 문자 집합에 대해 절대적으로 알아야 하는 절대 최소값(변명 없음