कोड की 1 पंक्ति में एक फ़ाइल खोलें और बंद करें


128

अब मैं उपयोग करता हूं:

pageHeadSectionFile = open('pagehead.section.htm','r')
output = pageHeadSectionFile.read()
pageHeadSectionFile.close()

लेकिन कोड बेहतर दिखने के लिए, मैं कर सकता हूं:

output = open('pagehead.section.htm','r').read()

उपरोक्त सिंटैक्स का उपयोग करते समय, मैं सिस्टम संसाधनों को मुक्त करने के लिए फ़ाइल को कैसे बंद करूं?


19
एक-लाइनर्स के बारे में स्वाभाविक रूप से अधिक आकर्षक कुछ भी नहीं है। कोड को लिखा जाने की तुलना में कहीं अधिक बार पढ़ा जाता है, और इसे समझ के लिए लिखा जाना चाहिए, न कि "शीतलता" के लिए। एकमात्र अपवाद तब है जब एक भाषा में एक प्रसिद्ध मुहावरा है, लेकिन मैं इस मामले में एक से अनजान हूं।
drdwilcox

17
@drdwilcox: Cryptic one-liners खराब हैं, घोषणात्मक one-liners अच्छे हैं। कोई कारण नहीं है (कम से कम मैं एक नहीं देख सकता), क्यों एक फ़ंक्शन कॉल में एक फ़ाइल (ऐसी सामान्य आवश्यकता) पढ़ने के लिए कोर में कोई फ़ंक्शन आवरण नहीं है। कुछ इस तरह contents = os.readfile(path)। अगर मैं कुछ कट्टर करना चाहता था, तो ठीक है, मैं खुशी से उपयोग करूँगा with open(path) as fd: contents = fd.read()। बेशक कोई भी अपना रैपर लिख सकता है, लेकिन यह वही है जो कोर के लिए है, प्रोग्रामर को उपयोगी सार प्रदान करने के लिए।
tokland

5
यह सच है कि कोड जितना लिखा गया है, उससे कहीं अधिक पढ़ा जाता है, लेकिन निहितार्थ यह है कि अब कोड उतना ही अच्छा है जितना कि शॉर्ट कोड अधिक गलत नहीं हो सकता। यदि आप अपने कोड को जितना संभव हो उतना कम करने में समय लगाते हैं (यह समझने के लिए कठिन चालाक चालों का सहारा लिए बिना), तो उस कोड को पढ़ने पर निवेश का भुगतान करना होगा। आपके द्वारा लिखी गई प्रत्येक पंक्ति आपके कोड को पढ़ने वाले किसी भी व्यक्ति के लिए एक असंतोष है, इसलिए आपको यथासंभव कम लिखने का प्रयास करना चाहिए। पास्कल के प्रसिद्ध उद्धरण को याद रखें: "मैंने यह पत्र केवल इसलिए लंबा किया क्योंकि मुझे इसे छोटा करने के लिए अवकाश नहीं मिला है।"
जॉन विलियम्स

जवाबों:


195

आपको वास्तव में इसे बंद करने की आवश्यकता नहीं है - अजगर संग्रह के दौरान या कार्यक्रम से बाहर निकलने के दौरान इसे स्वचालित रूप से करेगा। लेकिन जैसा कि @delnan ने कहा, विभिन्न कारणों से इसे स्पष्ट रूप से बंद करना बेहतर अभ्यास है।

तो, आप इसे छोटा, सरल और स्पष्ट रखने के लिए क्या कर सकते हैं:

with open('pagehead.section.htm','r') as f:
    output = f.read()

अब यह सिर्फ दो पंक्तियों और बहुत पठनीय है, मुझे लगता है।


2
@ 1qxxsw2 यदि आप withकथन का उपयोग करते हैं तो फ़ाइल संसाधन आपके लिए ठीक से बंद हो जाएगा।
डेविड अल्बर्ट

13
पहला वाक्य: पायथन अंततः इसे बंद कर देगा । लेकिन इसका मतलब यह नहीं है कि आपको बंद करने के बारे में भूल जाना चाहिए। यहां तक ​​कि refcounting के साथ, फ़ाइल आपके विचार और अपेक्षा से अधिक समय तक खुली रह सकती है (उदाहरण के लिए यदि यह चक्र द्वारा संदर्भित किया जाता है)। यह पायथन कार्यान्वयन में तीन बार जाता है जिसमें एक सभ्य जीसी होता है, जहां आपको कोई गारंटी नहीं है कि किसी भी विशेष समय पर GC'd है। यहां तक ​​कि सीपीथॉन प्रलेखन का कहना है कि आपको इस तरह से सफाई के लिए जीसी पर भरोसा नहीं करना चाहिए। उत्तर का उत्तरार्द्ध बोल्ड होना चाहिए।

6
यदि आपको वास्तव में वन-लाइनर की आवश्यकता है , तो output = f.read()भाग को उसी लाइन पर रखना संभव है :
कार्ल केनचेल

1
"1 लाइन के कोड में एक फ़ाइल खोलें और बंद करें" यह दो लाइनें हैं, और इस सवाल का जवाब नहीं देती हैं।
user5359531

1
यह कार्यान्वयन पर निर्भर है - स्वेन का जवाब देखें।
टिम पीटरज़

71

पायथन स्टैंडर्ड लाइब्रेरी पैथलिब मॉड्यूल वह काम करता है जिसकी आपको तलाश है:

Path('pagehead.section.htm').read_text()

पथ आयात करना न भूलें:

jsk@dev1:~$ python3
Python 3.5.2 (default, Sep 10 2016, 08:21:44)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pathlib import Path
>>> (Path("/etc") / "hostname").read_text()
'dev1.example\n'

पाइथन 27 पर बैकपोर्ट pathlibया स्थापित करेंpathlib2


8
प्रस्ताव करने वाले अन्य उत्तर withठीक हैं, लेकिन withएक बयान है, एक अभिव्यक्ति नहीं है। यह pathlibउत्तर मूल प्रश्न का एकमात्र उत्तर है जिसे पायथन अभिव्यक्ति में एम्बेड किया जा सकता है। कुछ इस तरहSECRET_KEY = os.environ.get('SECRET_KEY') or pathlib.Path('SECRET_KEY').read_bytes()
लियो रोसैल

24

CPython का उपयोग करते हुए, लाइन निष्पादित होने के तुरंत बाद आपकी फ़ाइल बंद हो जाएगी, क्योंकि फ़ाइल ऑब्जेक्ट तुरंत कचरा एकत्र किया जाता है। हालांकि, दो कमियां हैं:

  1. अजगर से अलग अजगर के कार्यान्वयन में, फ़ाइल अक्सर तुरंत बंद नहीं होती है, बल्कि बाद के समय में आपके नियंत्रण से परे होती है।

  2. पायथन 3.2 या उससे ऊपर, यह ResourceWarningसक्षम होने पर, फेंक देगा ।

एक अतिरिक्त लाइन निवेश करने के लिए बेहतर है:

with open('pagehead.section.htm','r') as f:
    output = f.read()

यह सुनिश्चित करेगा कि फ़ाइल सभी परिस्थितियों में सही ढंग से बंद है।


17

ऐसा करने के लिए किसी विशेष पुस्तकालयों को आयात करने की आवश्यकता नहीं है।

सामान्य सिंटैक्स का उपयोग करें और यह फ़ाइल को पढ़ने के लिए खोल देगा फिर इसे बंद करें।

with open("/etc/hostname","r") as f: print f.read() 

या

with open("/etc/hosts","r") as f: x = f.read().splitlines()

जो आपको एक एक्सरे देता है जिसमें लाइनें हैं, और इसे इस तरह प्रिंट किया जा सकता है:

for line in x: print line

ये वन-लाइनर्स रखरखाव के लिए बहुत सहायक हैं - मूल रूप से स्व-दस्तावेजीकरण।


8

withकथन का उपयोग करने के लिए आप क्या कर सकते हैं , और दो चरणों को एक पंक्ति में लिखें:

>>> with open('pagehead.section.htm', 'r') as fin: output = fin.read();
>>> print(output)
some content

withबयान कॉल करने के लिए देखभाल करेगा __exit__दिया वस्तु भले ही कुछ बुरा अपने कोड में हुआ समारोह; यह try... finallyवाक्य रचना के करीब है । द्वारा लौटाए गए ऑब्जेक्ट के लिए open, __exit__फ़ाइल बंद करने से संबंधित है।

इस बयान को पायथन 2.6 के साथ पेश किया गया है।


लघु स्पष्टीकरण: प्रलेखन के अनुसार withअजगर 2.5 में पेश किया गया था, लेकिन इसे स्पष्ट रूप से आयात किया जाना था __future__। यह पाइथन 2.6 में सभी संदर्भों से उपलब्ध हुआ।
डेविड अल्बर्ट

5

ilio का उपयोग करें : (इनलाइन io):

फ़ाइल ओपन (), रीड (), क्लोज़ () के बजाय केवल एक फ़ंक्शन कॉल।

from ilio import read

content = read('filename')

2
with open('pagehead.section.htm')as f:contents=f.read()

4
यह शीर्ष 3 उत्तरों से कैसे अलग है?
सभी मजदूरों की आवश्यक संख्या

4
सबसे बड़ा अंतर यह है कि निर्दिष्ट प्रश्न के रूप में यह केवल एक पंक्ति है। व्यक्तिगत रूप से मुझे इससे परे कोई भी नहीं मिल सकता है, लेकिन वास्तव में सवाल का योगदान करने के बजाय अपने काम की आलोचना करने के लिए स्वतंत्र महसूस करें।

3
पायथन में किसी फ़ाइल को खोलने, पढ़ने और प्राप्त करने के लिए कम से कम, बिल्ट-इन तरीका 2 तार्किक लाइनों का उपयोग कर रहा है, चाहे वह 1 लाइन के नीचे घनीभूत हो या नहीं। इसलिए मुझे यह उत्तर 3 मूल उत्तरों से प्रभावी रूप से भिन्न नहीं लगता है।
सभी कार्यकर्ता

1
इससे कोई फर्क नहीं पड़ता कि इसका its प्रभावी रूप से ’अलग है। मुझे इस पृष्ठ पर एक-लाइन सिंटैक्स की तलाश थी जो कि python -cकमांड लाइन पर उपयोग किया जा सकता है , इसलिए 2-लाइन उत्तर पोस्ट करने से मदद नहीं मिलती है।
user5359531

1
@ user5359531 मैं आपकी बात नहीं देखता: क्या आप जानते हैं कि आप अजगर के भावों को उद्धृत कर सकते हैं ", ;दो निर्देशों को जोड़ सकते हैं, और उसके बाद नई लाइन हटा सकते हैं :? निम्नलिखित अभिव्यक्ति मेरे लिए ठीक काम करती है:$> python -c "with open('some file', 'r') as f: print(next(f))"
जोएल

2

मुझे लगता है कि इसे प्राप्त करने का सबसे स्वाभाविक तरीका एक फ़ंक्शन को परिभाषित करना है।

def read(filename):
    f = open(filename, 'r')
    output = f.read()
    f.close()
    return output

तो आप निम्नलिखित कर सकते हैं:

output = read('pagehead.section.htm')

0

मैं अक्सर ऐसा कुछ करता हूं, जब मुझे एक लॉग फ़ाइल में कुछ छांटने के लिए कुछ पंक्तियाँ प्राप्त करने की आवश्यकता होती है:

$ grep -n "xlrd" requirements.txt | awk -F ":" '{print $1}'
54

$ python -c "with open('requirements.txt') as file: print ''.join(file.readlines()[52:55])"
wsgiref==0.1.2
xlrd==0.9.2
xlwt==0.7.5

1
पूरी तरह से मूल विषय से संबंधित न, लेकिन आप इस पर गौर करना चाहिए grep -A <n>, grep -B <n>और grep -C <n>, अगर यह उपयोगी है। अधिक जानकारी: stackoverflow.com/a/9083/1830159
लियाम स्टेनली

0

उपयोग करना more_itertools.with_iter, outputएक पंक्ति में (आयात विवरण को छोड़कर) एक समकक्ष को खोलना, पढ़ना, बंद करना और असाइन करना संभव है :

import more_itertools as mit


output = "".join(line for line in mit.with_iter(open("pagehead.section.htm", "r")))

यद्यपि संभव है, मैं एक फ़ाइल की सामग्री को एक चर के लिए असाइन करने के अलावा अन्य दृष्टिकोण की तलाश करूंगा, अर्थात आलसी पुनरावृत्ति - यह एक पारंपरिक withब्लॉक का उपयोग करके या ऊपर दिए गए उदाहरण में इसे हटाकर join()और पुनरावृत्ति करके किया जा सकता है output


आप ऑनलाइनर के अंदर भी आयात कर सकते हैं। "".join(line for line in __import__('more_itertools').with_iter(open("pagehead.section.htm", "r")))यह ठीक काम करता है, और आयात के लिए एक पंक्ति की आवश्यकता को समाप्त करता है।
मेल्विल

1
मैं पूर्णतः सन्तुष्ट हुँ। हालाँकि, ऑनलाइनर्स के साथ सुलझाने के कार्यों पर चर्चा करते हुए, मैंने अक्सर अपने आप को उन तर्कों में पाया है जहाँ सहमत परिणाम एक नए अजगर के खोल में चिपकाए गए कोड की एक पंक्ति होनी चाहिए। ऐसी चुनौतियां शायद ही कभी pep8 के अनुरूप हों। यह किसी भी तरह से कोड लिखने के लिए एक अच्छा अभ्यास नहीं है, यह केवल आयात की आवश्यकता को दूर करने के लिए एक टिप के रूप में था।
मेलविल

0

आपको लगता है कि गर्म और फजी महसूस कर रही चाहते हैं, बस के साथ जाने के साथ

अजगर 3.6 के लिए, मैंने IDLE की एक नई शुरुआत के तहत इन दो कार्यक्रमों को चलाया:

0.002000093460083008  Test A
0.0020003318786621094 Test B: with guaranteed close

इतना अंतर नहीं है।

#--------*---------*---------*---------*---------*---------*---------*---------*
# Desc: Test A for reading a text file line-by-line into a list
#--------*---------*---------*---------*---------*---------*---------*---------*

import sys
import time

#                                  # MAINLINE
if __name__ == '__main__':
    print("OK, starting program...")

    inTextFile = '/Users/Mike/Desktop/garbage.txt'

#                                  # Test: A: no 'with;
    c=[]
    start_time = time.time()
    c = open(inTextFile).read().splitlines()
    print("--- %s seconds ---" % (time.time() - start_time))

    print("OK, program execution has ended.")
    sys.exit()                     # END MAINLINE

उत्पादन:

OK, starting program...
--- 0.002000093460083008 seconds ---
OK, program execution has ended.

#--------*---------*---------*---------*---------*---------*---------*---------*
# Desc: Test B for reading a text file line-by-line into a list
#--------*---------*---------*---------*---------*---------*---------*---------*

import sys
import time

#                                  # MAINLINE
if __name__ == '__main__':
    print("OK, starting program...")

    inTextFile = '/Users/Mike/Desktop/garbage.txt'

#                                  # Test: B: using 'with'
    c=[]
    start_time = time.time()
    with open(inTextFile) as D: c = D.read().splitlines()
    print("--- %s seconds ---" % (time.time() - start_time))

    print("OK, program execution has ended.")
    sys.exit()                     # END MAINLINE

उत्पादन:

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