Python 3 open (encoding =“utf-8”)을 Python 2로 백 포트


152

Python 3 용으로 작성된 Python 코드베이스가 있는데 인코딩 매개 변수와 함께 Python 3 스타일 open ()을 사용합니다.

https://github.com/miohtama/vvv/blob/master/vvv/textlineplugin.py#L47

    with open(fname, "rt", encoding="utf-8") as f:

이제이 코드를 Python 2.x로 백 포트하여 Python 2 및 Python 3에서 작동하는 코드베이스를 만들려고합니다.

open()차이점과 인코딩 매개 변수 부족 을 해결하기 위해 권장되는 전략은 무엇입니까 ?

open()바이트 문자열을 스트리밍 하는 Python 3 스타일 파일 처리기를 가질 수 있으므로 Python 2처럼 작동 open()합니까?

답변:


176

1. 파이썬 2에서 인코딩 파라미터를 얻으려면 :

Python 2.6 및 2.7 만 지원해야하는 경우 io.open대신 대신 사용할 수 있습니다 open. ioPython 3의 새로운 io 하위 시스템이며 Python 2,6 및 2.7에도 있습니다. 파이썬 2.6 (및 3.0)에서는 순수하게 파이썬으로 구현되고 매우 느리므로 파일을 읽는 데 속도가 필요한 경우 좋은 옵션이 아닙니다.

속도가 필요하고 Python 2.6 또는 이전 버전을 지원해야하는 경우 codecs.open대신 사용할 수 있습니다 . 또한 인코딩 매개 변수가 있으며 io.open줄 끝을 다르게 처리한다는 점 을 제외 하고는 매우 유사합니다 .

2. open()바이트 열을 스트리밍 하는 Python 3 스타일 파일 핸들러 를 얻으려면 :

open(filename, 'rb')

'이진'을 의미하는 'b'에 유의하십시오.


11
'b'는 실제로 바이트가 아닌 이진 모드를 의미합니다. docs.python.org/3/library/functions.html#open을 참조하십시오 .
pmdarrow

7
@pmdarrow이 경우에도 똑같지 만 엄밀히 말하면 그렇습니다.
Lennart Regebro 8

옵션 2;)에 대해 바이트 스트림을 통해 정규식을 실행할 수 없다는 문제가 발생했습니다.
Jonathan Komar

3
@ macmadness86 바이트 정규 표현식을 사용해야합니다.
Lennart Regebro

4
포팅 하우투의 메모 : "파이썬 2.5와의 호환성을 유지하기 위해서만 필요한 codecs.open ()을 사용하는 구식 관행에 신경 쓰지 마십시오." docs.python.org/3/howto/pyporting.html
Al Sweigart

65

나는 생각한다

from io import open

해야 할 것.


7
Lennart의 응답은 codecs.open 사용 제안과 함께 2.x에서 io 모듈에 대한 자세한 설명과주의 사항을 제공하기 때문에 훨씬 더 좋습니다.
gps

2
from io import openPython 3에서 사용하면 어떻게됩니까 ? 현재 성능에 관심이 없습니다.
matth

8
@matth python3에서 io로 열기는 내장 열기의 별칭입니다. 참조 docs.python.org/3/library/io.html?highlight=io#io.open
mfussenegger

21

한 가지 방법이 있습니다.

with open("filename.txt", "rb") as f:
    contents = f.read().decode("UTF-8")

4
당신이 다른 계획을 가지고 있다면 이것은 분명히 작동하지 않습니다f
user5359531

8

이것은 트릭을 할 수 있습니다 :

import sys
if sys.version_info[0] > 2:
    # py3k
    pass
else:
    # py2
    import codecs
    import warnings
    def open(file, mode='r', buffering=-1, encoding=None,
             errors=None, newline=None, closefd=True, opener=None):
        if newline is not None:
            warnings.warn('newline is not supported in py2')
        if not closefd:
            warnings.warn('closefd is not supported in py2')
        if opener is not None:
            warnings.warn('opener is not supported in py2')
        return codecs.open(filename=file, mode=mode, encoding=encoding,
                    errors=errors, buffering=buffering)

그런 다음 python3 방식으로 코드를 유지할 수 있습니다.

일부 API를 좋아하는 것으로 newline, closefd, opener작동하지 않습니다


1
이를 피하기 위해 조건을 되돌릴 수 있습니다 pass.
bfontaine

2

당신이 사용하는 경우 six, 당신은있는 최신 파이썬 3 API를 사용하고 모두 파이썬 2/3에서 실행할 수있는이 시도 할 수 있습니다 :

import six

if six.PY2:
    # FileNotFoundError is only available since Python 3.3
    FileNotFoundError = IOError
    from io import open

fname = 'index.rst'
try:
    with open(fname, "rt", encoding="utf-8") as f:
        pass
        # do_something_with_f ...
except FileNotFoundError:
    print('Oops.')

그리고 Python 2 지원 포기는 관련 모든 것을 삭제합니다 six.

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