Python 3'ü Python 2'ye açık (kodlama = “utf-8”)


152

Kodlama parametresi ile Python 3 stili open () kullanan Python 3 için inşa edilmiş bir Python kod temeli var:

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

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

Şimdi Python 2 ve Python 3 ile çalışan bir kod temeli olurdu, bu kodu Python 2.x backport istiyorum.

open()Farklılıklar ve kodlama parametresi eksikliği üzerinde çalışmak için önerilen strateji nedir ?

open()Bytestrings akarsu Python 3 tarzı bir dosya işleyicisi olabilir, bu yüzden Python 2 gibi davranır open()?

Yanıtlar:


177

1. Python 2'de bir kodlama parametresi almak için:

Yalnızca Python 2.6 desteklemesi gerekiyor ve 2.7 Eğer kullanabilirsiniz io.openyerine open. ioPython 3 için yeni io alt sistemidir ve Python 2,6 ve 2.7 sürümlerinde de mevcuttur. Python 2.6'da (3.0'ın yanı sıra) tamamen python'da uygulandığını ve çok yavaş olduğunu unutmayın, bu nedenle dosya okuma hızına ihtiyacınız varsa, iyi bir seçenek değildir.

Hıza ihtiyacınız varsa ve Python 2.6 veya önceki sürümlerini desteklemeniz gerekiyorsa, codecs.openbunun yerine kullanabilirsiniz . Ayrıca bir kodlama parametresi vardır ve io.opensatır sonlarını farklı işlemesi dışında oldukça benzerdir .

2. open()Bytestrings akışını sağlayan bir Python 3 stili dosya işleyici almak için :

open(filename, 'rb')

'İkili' anlamına gelen 'b'ye dikkat edin.


11
'B' aslında bayt değil, ikili mod anlamına gelir. Bkz. Docs.python.org/3/library/functions.html#open .
pmdarrow

7
@pmdarrow Bu durumda aynı şey, ama kesinlikle konuşursak, evet.
Lennart Regebro

Seçenek 2 için bir bayt akışı üzerinde regex çalıştıramama sorunu ile karşılaştım;)
Jonathan Komar

3
@ macmadness86 Bayt regexp ifadesi kullanmanız gerekir.
Lennart Regebro

4
Taşıma yönteminden bir not: "Sadece Python 2.5 ile uyumluluğu korumak için gerekli olan codecs.open () yöntemini kullanma konusunda eski uygulamalarla uğraşmayın." docs.python.org/3/howto/pyporting.html
Al Sweigart

65

bence

from io import open

yapmak gerekir.


7
Lennart'ın aşağıdaki yanıtı, daha fazla açıklama sağladığından ve io modülü hakkındaki uyarının codecs.open kullanma önerisiyle birlikte 2.x'te yavaş olduğu için çok daha iyi olduğunu düşünüyorum.
gps

2
from io import openPython 3'te kullanırsam ne olur ? Şu anda performans umurumda değil.
matth

8
@matth io'dan açılan python3'te dahili açık için bir takma addır. Bkz. Docs.python.org/3/library/io.html?highlight=io#io.open
mfussenegger

21

İşte bir yol:

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

4
için farklı planları olsaydı bu besbelli çalışmıyorf
user5359531

8

Bu hile yapabilir:

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)

Sonra kod python3 şekilde tutabilirsiniz.

Bazı API'ler gibi Not olduğunu newline, closefd, openeriş yok


1
bundan kaçınmak için durumu tersine çevirebilirsiniz pass.
bfontaine

2

Kullanıyorsanız six, bunu en son Python 3 API'sını kullanarak deneyebilir ve her iki Python 2/3'te çalıştırabilirsiniz:

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.')

Ve, Python 2 desteği terk sadece ilgili her şeyi silmek six.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.