Python에서 open과 codecs.open의 차이점


95

Python에서 텍스트 파일을 여는 방법에는 두 가지가 있습니다.

f = open(filename)

import codecs
f = codecs.open(filename, encoding="utf-8")

언제이고 codecs.open바람직합니다 open?


45
codecs.open()이후, 3.X에서 사용되지 않습니다 open()이익 encoding인수입니다.
Ignacio Vazquez-Abrams 2011 년

세 번째 방법도 있습니다 (적어도 Python 2.x에서는) :`f = file (filename) '
Adam Parkin

1
@ IgnacioVazquez-Abrams codecs.open()쓸모없는 링크 가 있습니까? 나는 이것을 python3 문서에서 생각하지 않는다 : docs.python.org/3.7/library/codecs.html
varela

1
@varela : 언급 한 Python 문서 페이지에 "내장 된 open () 및 관련 io 모듈이 인코딩 된 텍스트 파일 작업에 권장되는 접근 방식입니다."
Luciano Ramalho

답변:


82

Python 2.6부터는을 사용하는 것이 좋습니다 io.open().이 역시 encoding이제 사용되지 않는 codecs.open(). Python 3에서는 내장 io.open의 별칭입니다 open(). 따라서 io.open()Python 2.6 및 Python 3.4를 포함한 모든 이후 버전에서 작동합니다. 문서 참조 : http://docs.python.org/3.4/library/io.html

이제 원래의 질문에 대한 : 읽을 때 텍스트를 당신이해야 파이썬 2 (HTML, XML 및 JSON "일반 텍스트"를 포함하여) 항상 사용 io.open()명시 적으로 인코딩을하거나, open()파이썬 3에 명시 적으로 인코딩을 이렇게 수단을 제대로 얻을 유니 코드를 디코딩하거나 즉시 오류가 발생하여 디버깅이 훨씬 쉬워집니다.

순수한 ASCII "일반 텍스트"는 먼 과거의 신화입니다. 적절한 영어 텍스트는 둥근 따옴표, em- 대시, 글 머리 기호, € (유로 기호) 및 분음 기호 (¨)를 사용합니다. 순진하지 마십시오! (그리고 Façade 디자인 패턴을 잊지 말자!)

순수한 ASCII는 실제 옵션이 아니기 때문에 open()명시 적 인코딩이 없으면 바이너리 파일 을 읽는 데만 유용 합니다.


5
@ForeverWintr 대답은 거기에 아주 분명하게 있습니다 : io.open()텍스트에 사용하고 open()바이너리에만 사용 합니다 . 의미는 codecs.open()전혀 선호되지 않는다는 것입니다.
Bdoserror

2
@Bdoserror,이 가 명확의 대답은하지만, 질문 한 질문에 대한 답이 아니다. 질문은 과 의 차이 , 특히 후자가 전자보다 더 나은 경우에 관한 것이 었습니다. 언급만큼 많지 않은 대답은 그 질문에 대답 할 수 없습니다. opencodecs.opencodecs.open
ForeverWintr 2017

3
@ForeverWintr OP가 잘못된 질문을 했다면 (즉, codecs.open()사용하기에 옳았다 는 가정하에 ) 언제 사용할 지에 대한 "정확한"대답이 없습니다. 대답은 io.open()대신 사용하는 것입니다. "벽에 못을 박을 때 렌치를 언제 사용해야합니까?"라고 묻는 것과 같습니다. 정답은 "망치 사용"입니다.
Bdoserror

20

개인적으로 저는 ** 를 사용해야하는 명확한 필요성이 확인되지 않는 한 항상 사용 합니다. 그 이유는 utf-8 입력이 내 프로그램에 몰래 들어가서 물린 적이 너무 많았 기 때문입니다. "오, 난 항상 아스키 일 거라는 걸 알아"는 가정이 자주 깨지는 경향이 있습니다.codecs.openopen

'utf-8'을 기본 인코딩으로 가정하면 ASCII가 UTF-8로 처리 될 수 있기 때문에 내 경험상 더 안전한 기본 선택이되는 경향이 있지만 그 반대는 사실이 아닙니다. 그리고 입력이 ASCII 라는 것을 진정으로 알고 있는 경우 에도 "명시적인 것이 암시적인 것보다 낫다"를codecs.open 확고하게 믿기 때문에 여전히 그렇게 합니다.

**-Python 2.x에서는 Python 3의 질문 상태에 대한 주석 opencodecs.open


내가 정말하지 않는 것은 왜 open... 때로는 아주 잘 유니 코드 세트의 UTF-8 인코딩 비 라틴어 문자를 처리 할 수 있으며, 경우에 따라서는 miserabily 실패
cedbeu

이것은 나에게 의미가 있습니다. io.open파이썬 2.7.5에서 볼 수있는 인코딩 매개 변수를 취하지 않습니다
radtek

1
@radtek, 이것이 문서화되지 않은 것이 맞습니다. 그러나 (2.7.12에서 적어도)을 io.open수용 encoding하고 newline파이썬 3처럼 매개 변수와 해석을. 달리 codecs.open와 열린 파일은 io.open올릴 것이다 TypeError: write() argument 1 must be unicode, not str당신이 쓰기를 시도하는 경우에도 파이썬 2.7 str( bytes그것에). 로 열린 파일 codecs.open은 대신으로 암시 적 변환을 시도하여 unicode종종 UnicodeDecodeErrors 를 혼란스럽게 만듭니다.
jochietoch

9

Python 2에는 유니 코드 문자열과 바이트 문자열이 있습니다. 바이트 스트링 만 사용하면 열린 파일을 읽고 쓸 수 있습니다 open(). 결국 문자열은 단지 바이트입니다.

문제는 예를 들어 유니 코드 문자열이 있고 다음을 수행 할 때 발생합니다.

>>> example = u'Μου αρέσει Ελληνικά'
>>> open('sample.txt', 'w').write(example)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

따라서 여기에서 분명히 유니 코드 문자열을 utf-8로 명시 적으로 인코딩하거나 codecs.open투명하게 수행하는 데 사용 합니다.

바이트 문자열 만 사용하는 경우 문제가 없습니다.

>>> example = 'Μου αρέσει Ελληνικά'
>>> open('sample.txt', 'w').write(example)
>>>

유니 코드와 바이트 스트링 문자열을 +연산자 와 연결하면 유니 코드 문자열을 얻게 되므로 이보다 더 복잡해집니다 . 그 사람에게 물기 쉽습니다.

또한 codecs.open비 ASCII 문자가 전달되는 바이트 문자열을 좋아하지 않습니다.

codecs.open('test', 'w', encoding='utf-8').write('Μου αρέσει')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/codecs.py", line 691, in write
    return self.writer.write(data)
  File "/usr/lib/python2.7/codecs.py", line 351, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)

입력 / 출력을위한 문자열에 대한 조언은 일반적으로 "가능한 한 빨리 유니 코드로 변환하고 가능한 한 늦게 바이트 문자열로 다시 변환"하는 것입니다. 를 사용 codecs.open하면 후자를 매우 쉽게 할 수 있습니다.

ASCII가 아닌 문자를 포함 할 수있는 바이트 문자열이 아닌 유니 코드 문자열을 제공한다는 점에주의하십시오.


두 번째 예를 설명해 주시겠습니까? 첫 번째 예와 동일 해 보이지만 결과가 다른 이유는 무엇입니까?
Chris Johnson

u''첫 번째 예에서 의 사용에 유의하십시오 . 즉, 바이트 문자열이 아닌 유니 코드 문자열을 만들었습니다. 이것이 두 예의 차이점입니다. 두 번째 예에서는 바이트 문자열을 만들고 그중 하나를 파일에 쓰는 것이 좋습니다. ASCII 이외의 문자를 사용하는 경우 유니 코드 문자열은 좋지 않습니다.
Mandible79 2017

7

특정 인코딩이있는 파일을 열려면 codecs모듈을 사용합니다 .


15
나는 모든 텍스트 파일이 어떻게 든 특정 인코딩을 가지고 있다고 생각합니다 (:
cedbeu

5

codecs.open, 내가 생각 Python 2하기에 빌트인 오픈이 훨씬 더 단순한 인터페이스와 더 적은 기능을 가졌던 시절 의 남은 것 입니다. Python 2에서 내장 open은 인코딩 인수를받지 않으므로 바이너리 모드 또는 기본 인코딩 이외의 것을 사용하려면 codecs.open을 사용해야합니다.

에서 Python 2.6의 IO 모듈은 상황이 조금 더 간단하게 원조에왔다. 공식 문서 에 따르면

New in version 2.6.

The io module provides the Python interfaces to stream handling.
Under Python 2.x, this is proposed as an alternative to the
built-in file object, but in Python 3.x it is the default
interface to access files and streams.

그렇긴 codecs.open하지만 현재 시나리오에서 내가 생각할 수있는 유일한 용도 는 이전 버전과의 호환성입니다. 다른 모든 시나리오에서는 (Python <2.6을 사용하지 않는 한) io.open. 또한 Python 3.x io.open다음과 같습니다.built-in open

노트 :

codecs.open와 사이 io.open에도 구문상의 차이가 있습니다.

codecs.open:

open(filename, mode='rb', encoding=None, errors='strict', buffering=1)

io.open:

open(file, mode='r', buffering=-1, encoding=None,
     errors=None, newline=None, closefd=True, opener=None)

뿐만 아니라 codecs.openio.open구문의 측면에서 차이, 서로 다른 유형의 개체를 반환합니다. 또한 codecs.open항상 바이너리 모드의 파일과 함께 작동합니다.
wombatonfire 2019

4
  • 바이너리 파일을로드하려면 f = io.open(filename, 'b').

  • 텍스트 파일을 열려면 항상 f = io.open(filename, encoding='utf-8')명시 적 인코딩을 사용하십시오.

에서 파이썬 3 하지만 open같은 일을 io.open대신 사용할 수 있습니다.

참고 : codecs.open더 이상 사용되지 않고 python 2.6에io.open 도입 된 후로 대체 될 예정 입니다. 코드가 이전 파이썬 버전과 호환되어야하는 경우에만 사용합니다. 파이썬의 코덱과 유니 코드에 대한 자세한 정보는 Unicode HOWTO를 참조하십시오 .


1. io.open또는 로 바이너리 모드에서 파일을 열 수없는 이유는 무엇 codecs.open입니까? 2. codecs.open아직 더 이상 사용되지 않습니다. 링크 한 페이지에서 토론을 읽으십시오.
wombatonfire 2019

좋은 포인트! 1. 둘 중 하나를 사용할 수 있지만 python 2.5 또는 이전 버전을 사용하지 않는 한 codecs.open에 대해 다시 조언하겠습니다. 2. 사용 중단이 즉시 발생하는 것이 아니라 미래에 발생했음을 반영하기 위해 답변을 업데이트했습니다.
wihlke

3

텍스트 파일로 작업하고 유니 코드 객체로 투명한 인코딩 및 디코딩을 원할 때.


0

.asm 파일을 열고 파일을 처리해야하는 상황에있었습니다.

#https://docs.python.org/3/library/codecs.html#codecs.ignore_errors
#https://docs.python.org/3/library/codecs.html#codecs.Codec.encode
with codecs.open(file, encoding='cp1252', errors ='replace') as file:

별 문제없이 전체 파일을 읽을 수 있습니다. 제안 사항이 있습니까?

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