J'ai un Python codebase, construit pour Python 3, qui utilise le style Python 3 open () avec le paramètre d'encodage:
https://github.com/miohtama/vvv/blob/master/vvv/textlineplugin.py#L47
with open(fname, "rt", encoding="utf-8") as f:
Maintenant, je voudrais effectuer un backport de ce code vers Python 2.x, de manière à disposer d'un code de base fonctionnant avec Python 2 et Python 3.
Quelle est la stratégie recommandée pour contourner open()
différences et manque de paramètre de codage?
Pourrais-je avoir un gestionnaire de fichier de style Python 3 open()
qui diffuse des chaînes de caractères, de sorte qu'il se comporte comme Python 2 open()
?
Si vous avez seulement besoin de supporter Python 2.6 et 2.7, vous pouvez utiliser io.open
au lieu de open
. io
est le nouveau sous-système io pour Python 3, et il existe également dans Python 2,6 et 2,7. Sachez que dans Python 2.6 (ainsi que dans la version 3.0), il est implémenté uniquement dans python et très lentement. Par conséquent, si vous avez besoin de vitesse de lecture, ce n’est pas une bonne option.
Si vous avez besoin de rapidité ou si vous devez prendre en charge Python 2.5 ou version antérieure, vous pouvez utiliser codecs.open
. Il possède également un paramètre de codage et est assez similaire à _io.open
_ sauf qu’il gère les fins de ligne différemment.
open()
qui diffuse des chaînes d'octets:_open(filename, 'rb')
_
Notez le "b", qui signifie "binaire".
Je pense
from io import open
devrait faire.
Voici un moyen:
with open("filename.txt", "rb") as f:
contents = f.read().decode("UTF-8")
Cela peut faire l'affaire:
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)
Ensuite, vous pouvez garder votre code de la manière python3.
Notez que certaines API telles que newline
, closefd
, opener
ne fonctionnent pas.
Si vous utilisez six
, vous pouvez essayer d’utiliser la dernière API Python 3 et de l’exécuter à la fois Python 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.')
Et, Python 2 support abandon, supprime simplement tout ce qui concerne six
.