홈으로 홈으로 | 무료회원가입 | 아이디/비번찾기 | 즐겨찾기
추천음악방송메인홈1대1상담음악방송청취
운.영.자.1대1.상담

온라이브음악방송
온라이브스토어(앱다운로드)
아리랑가요(무료음악채널)
뽕짝아가씨(무료음악채널)
okTrot(무료음악채널)
전통가요(무료음악채널)

환상의뽕짝파티 무료음악
명작트로트메들리 무료음악
트로트메들리관광 무료음악
동영상노래방
가사검색

POP Player
신나는 고스톱
컴퓨터 오목
작은 음악다방
최신 인기가요

보안∵서버∵쿠키
윈도우∵프레임
이미지∵배경
시간∵달력∵계산
상태바∵타이틀바
음악∵영상
폼∵전송∵테이블
키보드∵마우스
효과∵링크∵메뉴
Script∵php
기타
PHP 강좌
윈도우관련팁
웹관련팁
홈페이지제작팁
기본강좌
레지스트리
윈도우서버
리눅스서버
Android
파이썬에서 유니코드 스트림 다루기
3년 전
파이썬에서 유니코드를 다룰 때는 일반적으로 str.decode()와 unicode.encode() 메서드를 사용하여 unicode 타입과 str 타입을 상호 변환한다.

아래 예시에서는 'utf-16'으로 작성된 파일을 열어, 수직 탭(vertical tab) 코드포인트를 지운 다음, 'utf-8'로 저장한다. (깨진 XML을 다룰 때 이 방식이 매우 중요하다.)

# 파일 내용을 읽는다
with open("input.txt", "rb") as input:  
    data = input.read()

# 바이너리 데이터를 utf-16으로 디코딩한다
data = data.decode("utf-16")

# 수직 탭을 삭제한다
data = data.replace(u"\u000B", u"")

# 유니코드 데이터를 utf-8로 인코딩한다
data = data.encode("utf-8")

# 데이터를 utf-8로 저장한다
with open("output.txt", "wb") as output:  
    output.write(data)
엄청나게 큰 파일을 다룰 때가 아니라면 이 정도로도 충분하다. 하지만 큰 파일을 다룰 땐 모든 데이터가 메모리에 올라간다는 사실이 문제가 된다.

스트리밍 인코더/디코더 사용하기
파이썬 기본 라이브러리에는 codecs 모듈이 포함되어 있다. 이 모듈을 사용하면 파일을 조금씩 읽을 수 있고, 메모리에도 약간의 유니코드 데이터만 올라가게 된다.

codecs.open() 헬퍼 메서드를 사용하여 위의 예시를 최소한만 고쳐보자.

import codecs

# 입력 스트림과 출력 스트림을 연다
input = codecs.open("input.txt", "rb", encoding="utf-16")  
output = codecs.open("output.txt", "wb", encoding="utf-8")

# 유니코드 데이터 조각들을 스트리밍한다
with input, output:  
    while True:
        # 데이터 조각을 읽고
        chunk = input.read(4096)
        if not chunk:
            break
        # 수직 탭을 삭제한다
        chunk = chunk.replace(u"\u000B", u"")
        # 데이터 조각을 쓴다
        output.write(chunk)
파일은 끔찍해! 이터레이터 사용하기
파일은 다루기가 좀 지루하다. 복잡한 처리 과정에는 유니코드 데이터의 이터레이터를 다루는 편이 깔끔할 것이다.

아래는 iterdecode()를 사용하여, 파일을 유니코드 데이터 조각의 이터레이터로 읽는 효과적인 방법이다.

from functools import partial  
from codecs import iterdecode

# 특정 path의 파일을 유니코드 조각의 이터레이터로 리턴한다
def iter_unicode_chunks(path, encoding):  
    # 읽을 파일을 연다
    with open(path, "rb") as input:
        # 바이너리 파일을 바이너리 조각으로 변환한다
        binary_chunks = iter(partial(input.read, 1), "")
        # 바이너리 조각을 유니코드 조각으로 변환한다
        for unicode_chunk in iterdecode(binary_chunks, encoding):
            yield unicode_chunk
이제 iterencode() 메서드를 사용하여, 유니코드 조각의 이터레이터를 파일에 써보자.

from codecs import iterencode

# 유니코드 조각의 이터레이터를 특정 path의 파일에 쓴다
def write_unicode_chunks(path, unicode_chunks, encoding):  
    # 쓸 파일을 연다
    with open(path, "wb") as output:
        # 유니코드 조각을 바이너리로 변환한다
        for binary_chunk in iterencode(unicode_chunks, encoding):
            output.write(binary_chunk)
이 두 함수와 함께 유니코드 데이터의 스트림에서 수직 탭을 없애는 일이 마법 같이 끝난다(just becomes a case of plumbing everything together).

# 파일을 유니코드 조각 형태로 읽는다
unicode_chunks = iter_unicode_chunks("input.txt", encoding="utf-16")

# 유니코드 조각을 수정한다
unicode_chunks = (  
    chunk.replace(u"\u000B", u"")
    for chunk
    in unicode_chunks
)

# 유니코드 조각을 파일에 저장한다
write_unicode_chunks("output.txt", unicode_chunks, encoding="utf-8")  
거창하게 codecs 모듈을 사용해야 할까?
얼핏 그냥, str.decode()와 unicode.encode() 메서드를 사용하여 큰 file 객체를 바이너리 조각으로 읽고, 인코딩하고 디코딩하는 편이 간단하다고 생각할 수도 있겠다.

# 나쁜 예시. 이렇게 하지 마시오!

# 입력 스트림과 출력 스트림을 연다
with open("input.txt", "rb") as input, open("output.txt", "wb") as output:  
    # 바이너리 데이터 조각들을 순회한다
    while True:
        # 데이터 조각을 읽는다
        chunk = input.read(4096)
        if not chunk:
            break
        # 위험: 바이너리 데이터를 utf-16으로 디코딩한다
        chunk = chunk.decode("utf-16")
        # 수직 탭을 삭제한다
        chunk = chunk.replace(u"\u000B", u"")
        # 유니코드 데이터를 utf-8로 인코딩한다
        chunk = chunk.encode("utf-8")
        # 데이터 조각을 쓴다
        output.write(chunk)
불행히도 몇몇 유니코드 코드포인트는 바이너리 데이터의 한 바이트 이상으로 인코딩된다. 따라서 단순히 파일에서 바이트 조각들을 읽어서 decode() 메서드를 적용하면 예기치 않게 UnicodeDecodeError가 발생할 수도 있다. 이는 바이트 한 조각이 여러 바이트의 코드포인트로 분리되었기 때문이다.

codecs 모듈의 도구들을 사용하면 이러한 예기치 않은 충돌을 예방할 수 있다.

파이썬 3에서는?
파이썬 3에서는 훨씬 단순하게 유니코드 파일을 다룰 수 있다. 빌트인 메서드인 open()은 유니코드 데이터를 수정하거나 인코딩을 변경하는 데 필요한 기능을 포함하고 있다.

# 입력 스트림과 출력 스트림을 연다
input = open("input.txt", "rt", encoding="utf-16")  
output = open("output.txt", "wt", encoding="utf-8")

# 유니코드 데이터 조각들을 스트리밍한다
with input, output:  
    while True:
        # 데이터 조각을 읽고
        chunk = input.read(4096)
        if not chunk:
            break
        # 수직 탭을 삭제한다
        chunk = chunk.replace("\u000B", "")
        # 데이터 조각을 쓴다
        output.write(chunk)
파이썬 3의 시대다! 즐겁게 코딩하길!
추천추천 : 197 추천 목록
번호 제목
3,026
 여러 도메인들 간 쿠키 공유하기
3,025
 태그 사이에 있는 텍스트를 추출
3,024
 [JQuery] textbox focus on off일때 숫자 콤마 보여주기
3,023
 쿠키 생성,가져오기,삭제
3,022
 사용자 함수 모음
3,021
 마우스,키보드 제한 ( 오른쪽클릭,드래그,영역선택등..)
3,020
 [HTML5] <video> - DOM으로 제어하기
3,019
 HTML5 video 태그에서 영상 좌우반전
3,018
 PHP - 특정 태그 및 문자열 추출, 제거
3,017
 [PHP] define과 defined의 차이
3,016
 우클릭 완벽차단 스크립트
3,015
 iframe 높이 100% 맞추기
3,014
 curl 함수를 이용한 HTTP REFERER 변경
3,013
 윈도우10 시스템 파일 및 Dism 검사
3,012
 텍스트 줄바꿈, 글자자르기 CSS
3,011
 jQuery Mobile에서 유용한 코드 10가지.
3,010
 [PHP] dirname()함수와 $_SERVER 관련 상수들
3,009
 [PHP] 파일 크기, 사이즈 불러오는 함수, filesize()
3,008
 [jQuery] jQuery Quick API
3,007
 [ transition ] 링크 hover 색상 변화 속도 조절
3,006
 PHP 5.3.0 에서 사라진 함수들 대체
3,005
 어떤 파일들이 include 나 require 되었는지 확인하는 함수(get_included_files)
3,004
 PHP 날짜 형식 및 계산하기(날짜 더하고 빼기)
3,003
 jQuery Mobile에서 유용한 코드 10가지.
3,002
 값이 배열 안에 존재하는지 확인하는 in_array함수
3,001
 사용자가 웹브라우저에서 뒤로가기를 했을때 감지하는 방법
3,000
 [jQuery]버튼 활성화, 비활성화
2,999
 jQuery show() / hide() / toggle() 사용법
2,998
 jquery 여러가지 이벤트
2,997
 border-radius 속성
2,996
 네이버 오픈API 음성합성 API 사용하는 PHP 샘플코드
2,995
 UTF8 한글 자르기..
2,994
 iconv 에러 발생시 계속 처리하기 옵션
2,993
 [PHP] 현재 페이지의 도메인 , URL 정보 알아내기.
2,992
 [PHP] 막강 기능 배열..
목록
추억의가요방(가사포함)
인기절정뽕짝파티
인기트로트모음
지루박디스코메들리
밤무대애창곡
전자올겐경음악
세월따라노래따라
가슴시린트로트
트로트쌍쌍파티
7080추억속으로
종합성인가요방
못잊을옛날노래
카바레 음악
트롯디스코팡팡
관광 메들리
트롯카페
가요감상실
추억의옛노래
스페셜가요광장
BillBoard Free
추천가요모음
경음악.전자올겐
스페셜음악여행
WOLRD POPs
K-POP\BillBoard
POP TOP BEST

최신인기가요특집
추천가요\인기
F뮤직 인기\발라드
F뮤직 애창\트로트
트로트성인가요
인기가요
프리미엄 POP
경음악\기타
프리미엄 최신가요
프리미엄 성인가요
가요축제\트롯1번지
댄스\메들리\리믹스
카페\명상\경음악\기타
뮤직트로트 부산광역시부산진구 가야동 ㅣ 개인정보취급방침
Copyright (C) musictrot All rights reserved.