पाइथन में खुले और कोडेकोपेन के बीच अंतर


93

पायथन में टेक्स्ट फ़ाइल खोलने के दो तरीके हैं:

f = open(filename)

तथा

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

कब करना codecs.openबेहतर है open?


44
ध्यान दें कि codecs.open()3.x में अप्रचलित है, चूंकि open()एक encodingतर्क प्राप्त होता है।
इग्नासियो वाज़केज़-अब्राम्स

एक तीसरा तरीका भी है (पायथन 2.x में कम से कम): `f = फ़ाइल (फ़ाइल नाम) '
एडम पार्किं नो

1
@ IgnacioVazquez-Abrams क्या कोई लिंक codecs.open()अप्रचलित है? मुझे ऐसा नहीं लगता है कि python3 डॉक्स में: docs.python.org/3.7/library/codecs.html
varela

1
@varela: आपके द्वारा उल्लेखित पायथन डॉक्यूमेंटेशन पेज कहता है: "बिलियन ओपन () और संबंधित io मॉड्यूल एन्कोडेड टेक्स्ट फाइलों के साथ काम करने के लिए अनुशंसित दृष्टिकोण हैं"
लुसियानो रामलहो

जवाबों:


82

पाइथन 2.6 के बाद से, एक अच्छा अभ्यास का उपयोग करना है io.open(), जो encodingअब अप्रचलित की तरह एक तर्क भी लेता है codecs.open()। पायथन 3 में, बिल्ट-इन के io.openलिए एक उपनाम open()है। इसलिए io.open()पाइथन 2.6 और बाद के सभी संस्करणों में काम करता है, जिसमें पाइथन 3.4 शामिल है। डॉक्स देखें: http://docs.python.org/3.4/library/io.html

अब, मूल प्रश्न के लिए: जब पायथन 2 में पाठ ("सादा पाठ", HTML, XML और JSON सहित) पढ़ते हैं , तो आपको हमेशाio.open() एक स्पष्ट एन्कोडिंग के open()साथ , या पायथन 3 में एक स्पष्ट एन्कोडिंग के साथ उपयोग करना चाहिए । ऐसा करने से आपको सही तरीके से प्राप्त होता है डिकोड किए गए यूनिकोड, या बल्ले से एक त्रुटि प्राप्त करें, जिससे डिबग करना बहुत आसान हो जाता है।

शुद्ध ASCII "सादा पाठ" दूर अतीत से एक मिथक है। उचित अंग्रेजी पाठ घुंघराले उद्धरण, इम-डैश, बुलेट, € (यूरो संकेत) और यहां तक ​​कि डायरिसिस (ly) का उपयोग करता है। भोले मत बनो! (और फ़ेकडे डिज़ाइन पैटर्न को नहीं भूलना चाहिए!)

क्योंकि शुद्ध ASCII एक वास्तविक विकल्प नहीं है, open()बिना स्पष्ट एन्कोडिंग केवल बाइनरी फ़ाइलों को पढ़ने के लिए उपयोगी है ।


5
@ForeverWintr उत्तर स्पष्ट रूप से वहाँ है: io.open()पाठ के लिए उपयोग करें, और open()केवल बाइनरी के लिए। निहितार्थ यह है कि codecs.open()बिल्कुल पसंद नहीं किया जाता है।
Bdoserror

2
@Bdoserror, वहाँ एक जवाब है, स्पष्ट रूप से, लेकिन यह उस सवाल का जवाब नहीं है जो पूछा गया था। सवाल के बीच अंतर के बारे में था openऔर codecs.openहै, और विशेष रूप से जब उसे पूर्व करने के लिए बेहतर है। एक उत्तर जो इतना अधिक नहीं है जितना कि उल्लेख codecs.openउस प्रश्न का उत्तर नहीं दे सकता है।
फॉरएवरविंटर

3
@ForeverWintr अगर ओपी ने गलत सवाल पूछा (यानी इस धारणा के साथ कि codecs.open()इसका उपयोग करने के लिए सही था) तो इसका उपयोग करने के बारे में कोई "सही" जवाब नहीं है। उत्तर io.open()इसके बजाय उपयोग करना है। यह ऐसा है जैसे कि मैं पूछता हूं "मुझे दीवार में कील चलाने के लिए रिंच का उपयोग कब करना चाहिए?"। सही उत्तर "एक हथौड़ा का उपयोग करें" है।
Bdoserror

20

व्यक्तिगत रूप से, मैं हमेशा उपयोग करता हूं codecs.openजब तक कि एक स्पष्ट पहचान की आवश्यकता न हो open**। कारण यह है कि मेरे कार्यक्रमों में utf-8 इनपुट स्नीक होने से मुझे कई बार काट लिया गया है। "ओह, मुझे पता है कि यह हमेशा एएससीआई होगा" एक धारणा है जो अक्सर टूट जाती है।

'Utf-8' को डिफॉल्ट एन्कोडिंग मानते हुए मेरे अनुभव में एक सुरक्षित डिफॉल्ट विकल्प हो जाता है, क्योंकि ASCII को UTF-8 के रूप में माना जा सकता है, लेकिन यह कायल सच नहीं है। और उन मामलों में जब मैं वास्तव में जानता हूं कि इनपुट ASCII है, तो मैं अभी भी करता codecs.openहूं क्योंकि मैं "स्पष्ट रूप से अंतर्निहित से बेहतर है" में एक दृढ़ विश्वास रखता हूं ।

** - पायथन में 2.x, प्रश्न के रूप में पायथन 3 में राज्यों की टिप्पणी openहैcodecs.open


जो मुझे वास्तव में नहीं मिलता है वह यह है कि openकभी-कभी यूटीएफ -8 एनकोडेड गैर-लैटिन अक्षरों के यूनिकोड सेट को बहुत अच्छी तरह से क्यों संभाल सकता है, और कभी-कभी यह बुरी तरह से विफल हो जाता है ...
cedbeu

मुझे यह अर्थपूर्ण लग रहा है। io.openमैं अजगर से जो कुछ देख सकता हूं उससे एक एन्कोडिंग परम को नहीं लेता हूं 2.7.5
रेडटेक

1
@ ब्रैडटेक, आप सही कह रहे हैं कि यह अनिर्दिष्ट है; हालाँकि (कम से कम 2.7.12 में) io.openस्वीकार करता है encodingऔर newlineमापदंडों और उन्हें व्याख्या करता है जैसा कि पायथन 3 करता है। इसके विपरीत codecs.open, यदि आप इसे लिखने का प्रयास ( ) करने की कोशिश करते हैं, तो पाइथन 2.7 में भी खोली गई एक फाइल उठ io.openजाएगी । इसके साथ खोली गई फ़ाइल के बजाय अंतर्निहित रूपांतरण का प्रयास किया जाएगा , जो अक्सर भ्रामक है । TypeError: write() argument 1 must be unicode, not strstrbytescodecs.openunicodeUnicodeDecodeError
जॉचचॉच

9

पायथन 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गैर-एएससीआईआई चार्ट के साथ बाइटस्ट्रेस पसंद नहीं किया जा रहा है:

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)

इनपुट / ouput के लिए स्ट्रिंग्स के बारे में सलाह आम तौर पर "यूनिकोड को यथाशीघ्र रूपांतरित करने और देर से संभव के रूप में बाइटस्ट्रेस में वापस होती है"। उपयोग codecs.openकरने से आप बाद को बहुत आसानी से कर सकते हैं।

बस सावधान रहें कि आप इसे यूनिकोड स्ट्रिंग्स दे रहे हैं न कि बाइटस्ट्रेस जो कि गैर-एएससीआईआई अक्षर हो सकते हैं।


क्या आप अपना दूसरा उदाहरण बता सकते हैं? यह आपके पहले उदाहरण के समान प्रतीत होता है, इसलिए परिणाम कोई भिन्न क्यों होगा?
क्रिस जॉनसन

u''पहले उदाहरण में उपयोग पर ध्यान दें । इसका मतलब है कि मैंने एक यूनिकोड स्ट्रिंग बनाया है, न कि बाईटस्ट्रिंग। यह दो उदाहरणों के बीच का अंतर है। दूसरे उदाहरण में मैं एक बाइटस्ट्रिंग बना रहा हूं और उनमें से किसी एक फाइल को लिखना ठीक है। यदि आप ASCII के बाहर वर्णों का उपयोग कर रहे हैं तो एक यूनिकोड स्ट्रिंग ठीक नहीं है।
मंडिबल79

7

जब आपको एक फ़ाइल खोलने की आवश्यकता होती है जिसमें एक निश्चित एन्कोडिंग होती है, तो आप codecsमॉड्यूल का उपयोग करेंगे ।


15
मुझे लगता है कि सभी पाठ फ़ाइलों में एक निश्चित एन्कोडिंग है, किसी भी तरह (:
cedbeu

5

codecs.open, मुझे लगता है, केवल उन Python 2दिनों से एक अवशेष है जब अंतर्निहित खुले में बहुत सरल इंटरफ़ेस और कम क्षमताएं थीं। पायथन 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वर्तमान परिदृश्य में केवल एक ही उपयोग मैं सोच सकता हूँ कि यह बैकवर्ड संगतता के लिए है। अन्य सभी स्थितियों में (जब तक कि आप पायथन <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.openऔर io.openवाक्य रचना के संदर्भ में, वे विभिन्न प्रकार की वस्तुओं को वापस करते हैं। इसके अलावा codecs.openहमेशा द्विआधारी मोड में फाइलों के साथ काम करता है।
wombatonfire

4
  • जब आप एक बाइनरी फ़ाइल लोड करना चाहते हैं, तो उपयोग करें f = io.open(filename, 'b')

  • पाठ फ़ाइल खोलने के लिए, हमेशा उपयोग करें f = io.open(filename, encoding='utf-8') स्पष्ट एन्कोडिंग के साथ ।

में अजगर 3 तथापिopen के रूप में एक ही बात करता है io.openऔर बदले में इस्तेमाल किया जा सकता।

नोट: अजगर 2.6 में इसकी शुरूआत के बाद पदावनत और प्रतिस्थापित codecs.openकरने की योजना बनाई गई है । यदि कोड को पहले के अजगर संस्करणों के साथ संगत करने की आवश्यकता है तो मैं इसका उपयोग करूंगा। अजगर में कोडेक्स और यूनिकोड के बारे में अधिक जानकारी के लिए यूनिकोड HOWTO देखें ।io.open


1. मैं बाइनरी मोड में io.openया उसके साथ एक फाइल क्यों नहीं खोल सकता codecs.open? 2. codecs.openअभी तक पदावनत नहीं किया गया है, उस पृष्ठ पर चर्चा पढ़ें जिसे आपने लिंक किया है।
wombatonfire

अच्छे अंक! 1. आप या तो उपयोग कर सकते हैं, लेकिन मैं फिर से codecs.open के खिलाफ सलाह दूंगा जब तक आप 2.5 या उससे अधिक उम्र के नहीं होते। 2. मैंने अपने उत्तर को प्रतिबिंबित करने के लिए अद्यतन किया कि पदावनति तुरंत नहीं हुई, बल्कि भविष्य में हुई।
विहलके

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:

बहुत परेशानी के बिना मैं पूरी फाइल, किसी भी सुझाव को पढ़ने में सक्षम हूं?

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