अजगर 3 को वापस खोलने (एन्कोडिंग = "utf-8") पायथन 2 के लिए


152

मेरे पास एक पायथन कोडबेस है, जिसे पायथन 3 के लिए बनाया गया है, जो एन्कोडिंग पैरामीटर के साथ पायथन 3 स्टाइल ओपन () का उपयोग करता है:

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()अंतर और एन्कोडिंग पैरामीटर की कमी के आसपास काम करने के लिए अनुशंसित रणनीति क्या है ?

क्या मेरे पास पायथन 3 open()स्टाइल फाइल हैंडलर हो सकता है, जो बाइटस्ट्रीम को स्ट्रीम करता है, इसलिए यह पायथन 2 की तरह काम करेगा open()?

जवाबों:


176

1. पायथन 2 में एक एन्कोडिंग पैरामीटर प्राप्त करने के लिए:

यदि आपको केवल पायथन 2.6 और 2.7 का समर्थन करने की आवश्यकता है, तो आप io.openइसके बजाय उपयोग कर सकते हैं openioपायथन 3 के लिए नया io सबसिस्टम है, और यह पायथन 2,6 एन्स 2.7 में भी मौजूद है। कृपया ध्यान रखें कि पायथन 2.6 (साथ ही 3.0) यह पूरी तरह से अजगर में और बहुत धीमी गति से कार्यान्वित किया जाता है, इसलिए यदि आपको फ़ाइलों को पढ़ने में गति की आवश्यकता है, तो यह एक अच्छा विकल्प नहीं है।

यदि आपको गति की आवश्यकता है, और आपको पायथन 2.6 या उससे पहले का समर्थन करने की आवश्यकता है, तो आप codecs.openइसके बजाय उपयोग कर सकते हैं । इसमें एन्कोडिंग पैरामीटर भी है, और यह काफी हद तक समान है io.openसिवाय इसके कि यह लाइन-एंडिंग्स को अलग तरीके से संभालता है।

2. पायथन 3 open()स्टाइल फाइल हैंडलर प्राप्त करने के लिए जो बाइटस्ट्रीम को धारा देता है:

open(filename, 'rb')

'बी' पर ध्यान दें, जिसका अर्थ है 'बाइनरी'।


11
'बी' वास्तव में बाइनरी मोड का मतलब है, बाइट्स नहीं। Docs.python.org/3/library/functions.html#open देखें ।
सायबर

7
@pmdarrow इस मामले में एक ही बात है, लेकिन कड़ाई से बोलना, हाँ।
लेनार्ट रेगेब्र

मैं इस समस्या में भाग गया कि आप विकल्प 2 के लिए बाइट स्ट्रीम पर रेगेक्स नहीं चला सकते हैं?)
जोनाथन कोमार

3
@ macmadness86 आपको बाइट regexp अभिव्यक्ति का उपयोग करने की आवश्यकता है।
लेन्नर्ट रेगेब्र

4
पोर्टिंग हाउटो से एक नोट: "कोडेक्सोपेन () का उपयोग करने की पुरानी प्रथा से परेशान न हों क्योंकि यह केवल पायथन 2.5 के साथ संगतता बनाए रखने के लिए आवश्यक है।" docs.python.org/3/howto/pyporting.html
Al Sweigart

65

मुझे लगता है

from io import open

करना चाहिए।


7
मुझे लगता है कि नीचे दिए गए Lennart की प्रतिक्रिया बहुत बेहतर है क्योंकि यह अधिक स्पष्टीकरण प्रदान करता है और io मॉड्यूल के बारे में 2.x में धीमी गति से किया जा रहा है और कोडेकेक्सोपेन का उपयोग करने के सुझाव के साथ।
जीपीएस

2
यदि मैं from io import openपायथन 3 में उपयोग करता हूं तो क्या होगा ? मैं वर्तमान में प्रदर्शन की परवाह नहीं करता।
मैट

8
@ Ithth 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 तरीके से कोड रख सकते हैं।

ध्यान दें कि कुछ APIs चाहते newline, closefd, openerकाम नहीं करते


1
इससे बचने के लिए आप स्थिति को उल्टा कर सकते हैं pass
bfontaine

2

यदि आप उपयोग कर रहे हैं six, तो आप यह कोशिश कर सकते हैं, जिसके द्वारा नवीनतम पायथन 3 एपीआई का उपयोग किया जा सकता है और पायथन 3/2 दोनों में चल सकता है:

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

और, अजगर 2 समर्थन परित्याग से संबंधित सब कुछ हटा रहा है six

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.