"ইওএফ না থাকাকালীন" পাইথনের জন্য নিখুঁত অংশটি কী?


114

কিছু পাঠ্য ফাইল পড়তে, সি বা পাস্কেলে, আমি ইওএফ পর্যন্ত ডেটা পড়তে সর্বদা নিম্নলিখিত স্নিপেটগুলি ব্যবহার করি:

while not eof do begin
  readline(a);
  do_something;
end;

সুতরাং, আমি আশ্চর্য হয়েছি কীভাবে পাইথনে আমি এই সহজ এবং দ্রুত করতে পারি?

উত্তর:


190

লাইন পড়তে ফাইলের উপর লুপ করুন:

with open('somefile') as openfileobject:
    for line in openfileobject:
        do_something()

ফাইল অবজেক্টগুলি পুনরাবৃত্তিযোগ্য এবং EOF অবধি লাইন উপার্জন করে। পুনরুক্তিযোগ্য হিসাবে ফাইল অবজেক্ট ব্যবহার করা পারফরম্যান্ট রিডগুলি নিশ্চিত করতে একটি বাফার ব্যবহার করে।

আপনি স্টিডিনের সাথেও এটি করতে পারেন (ব্যবহার করার দরকার নেই raw_input():

import sys

for line in sys.stdin:
    do_something()

ছবিটি সম্পূর্ণ করতে, বাইনারি রিডগুলি দিয়ে করা যেতে পারে:

from functools import partial

with open('somefile', 'rb') as openfileobject:
    for chunk in iter(partial(openfileobject.read, 1024), b''):
        do_something()

যেখানে chunkফাইল থেকে একসাথে 1024 বাইট থাকবে এবং openfileobject.read(1024)খালি বাইট স্ট্রিংগুলি ফিরতে শুরু করলে পুনরাবৃত্তি থামে ।


4
দ্রষ্টব্য: lineশেষে একটি নতুন লাইনের অক্ষর থাকবে।
ben_joseph

1
জেনেরিক বাইনারি ফাইলগুলির জন্য লাইনগুলি পড়া কিছুটা বিপজ্জনক, কারণ সম্ভবত আপনার কাছে একটি 6GiB লম্বা লাইন রয়েছে ...
LtWorf

@LtWorf: যে কারণে আমি দেখাবো কিভাবে বাইনারি ফাইল পড়তে অংশ লাইন বদলে।
মার্টিজন পিটারস

আমি stdinএকটি চলমান প্রক্রিয়া থেকে একটি থেকে পড়ছি ... সুতরাং আমি প্রক্রিয়াটি না মেরে এটিতে কখনও ইওএফ থাকে না। তবে তারপরে আমি "এখন অবধি এখন" পৌঁছেছি এবং আমি অচল। আমি কীভাবে এটি সনাক্ত করতে পারি এবং অচলাবস্থা নেই? কোনও নতুন লাইন না থাকলে, ফাইলগুলি পড়া বন্ধ করুন (কোনও ইওএফ না থাকলেও, যা আমার ক্ষেত্রে কখনও উপস্থিত থাকবে না)।
চার্লি পার্কার 21

@ চর্লিপারপার্ক: আপনি যদি অচলাবস্থায় পৌঁছে যান তবে কিছু সম্ভবত সম্ভবত বাফারটি ফ্লাশ করতে ভুলে যাচ্ছে। প্রকৃত এমসিভিই ব্যতীত এর চেয়ে বেশি কিছু বলা শক্ত।
মার্টিজন পিটারস

61

আপনি পাইথনের সি আইডিয়মটি অনুকরণ করতে পারেন।

max_sizeবাইট সংখ্যা পর্যন্ত একটি বাফার পড়তে , আপনি এটি করতে পারেন:

with open(filename, 'rb') as f:
    while True:
        buf = f.read(max_size)
        if not buf:
            break
        process(buf)

বা, একটি পাঠ্য ফাইল লাইন লাইন:

# warning -- not idiomatic Python! See below...
with open(filename, 'rb') as f:
    while True:
        line = f.readline()
        if not line:
            break
        process(line)

আপনাকে while True / breakকন্সট্রাক্ট ব্যবহার করা দরকার যেহেতু পাইথনে কোনও পড়ার সময় থেকে ফিরে আসা বাইটের অভাব ছাড়া অন্য কোনও ইওফ টেস্ট নেই

সি তে, আপনার হতে পারে:

while ((ch != '\n') && (ch != EOF)) {
   // read the next ch and add to a buffer
   // ..
}

তবে পাইথনে আপনার এটি থাকতে পারে না:

 while (line = f.readline()):
     # syntax error

কারণ বরাদ্দকরণ এক্সপ্রেশন অনুমোদিত নয় পাইথনের (যদিও পাইথনের সাম্প্রতিক সংস্করণগুলি অ্যাসাইনমেন্ট এক্সপ্রেশনগুলি ব্যবহার করে এটি নকল করতে পারে, নীচে দেখুন)।

এটা অবশ্যই আরো পাইথন এই কাজ করার জন্য কথ্য:

# THIS IS IDIOMATIC Python. Do this:
with open('somefile') as f:
    for line in f:
        process(line)

আপডেট: পাইথন ৩.৮ থেকে আপনি অ্যাসাইনমেন্ট এক্সপ্রেশনও ব্যবহার করতে পারেন :

 while line := f.readline():
     process(line)

@MartijnPieters: এখন এটা আছে :-)
Dawg

3
সি এবং পার্ল প্রোগ্রামার হিসাবে, আপনার বক্তব্যটি যে অ্যাসাইনমেন্টগুলিতে প্রকাশের অনুমতি নেই তা আমার পক্ষে অত্যন্ত গুরুত্বপূর্ণ।
কোড

1
"যখন সত্য:" পদ্ধতিটি তখনও কার্যকর যখন যখন আপনাকে পুনরাবৃত্তি প্রতি একাধিক ইনপুট লাইনে কাজ করতে হবে, এমন কিছু যা আইডিয়োম্যাটিক পাইথন অনুমতি দেয় না (যতদূর আমি বলতে পারি)।
ডোনাল্ড স্মিথ

আপনি যদি ফাইলটিতে অনুমান না করেন তবে আপনাকে লাইনগুলি পড়তে হবে না। একটি বাইনারি ফাইলের বিশাল
আকারের

অ-অহঙ্কারী readline()পদ্ধতিতে এটির একটি সুবিধা রয়েছে বলে মনে হচ্ছে : আপনি ধরার মতো সূক্ষ্ম ত্রুটিযুক্ত ত্রুটি পরিচালনা UnicodeDecodeErrorকরতে পারেন, যা আপনি অহঙ্কারী forপুনরাবৃত্তির সাথে করতে পারবেন না ।
ফ্লো 2 কে

17

একটি ফাইল খোলার এবং এটি লাইন বাই লাইন পড়ার পাইথন আইডিয়ামটি হ'ল:

with open('filename') as f:
    for line in f:
        do_something(line)

উপরের কোডের শেষে ফাইলটি স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে ( withকনস্ট্রাক্ট এটির যত্ন নেয়)।

শেষ অবধি, এটি লক্ষণীয় যে এটি lineপূর্ববর্তী নিউলাইনটি সংরক্ষণ করবে। এটি ব্যবহার করে সহজেই সরানো যেতে পারে:

line = line.rstrip()

1
+1 টি, এছাড়াও ওপি যে এই হল ইশারা না অনুরূপ হিসাবে একই for line in f.readlines(): ..., একটি সাধারণভাবে প্রস্তাব সমাধান।
jedwards

12

আপনি ফাইল সীমা অবধি লাইনে লাইনে পড়তে কোড স্নিপেট ব্যবহার করতে পারেন

line = obj.readline()
while(line != ''):

    # Do Something

    line = obj.readline()

1
আইএমও, এটিই একটি উত্তর যা জিজ্ঞাসিত হয়েছিল তা প্রতিফলিত করে lects
gvrocha

প্রায়শই রেখাগুলির পুনরাবৃত্তি প্রোগ্রামটির কাঠামোকে বিকৃত করে দেয়। উদাহরণস্বরূপ, কোনও ভাষা পার্সারে আপনি লাইনগুলি পড়তে এবং ক্রমক্রমে প্রসেস করতে চান। আপনি শীর্ষ স্তরের পুনর্গঠন করতে চান না যাতে আপনি পড়ার লাইনগুলি লুপ করতে পারেন এবং তারপরে পার্সারে প্রেরণ করতে পারেন।
জোনাথন স্টার

11

"এটি অজগর পথে করার জন্য" উপরে প্রস্তাবনা রয়েছে, তবে কেউ যদি ইওএফ-এর উপর ভিত্তি করে যুক্তি রাখতে চায় তবে আমি মনে করি ব্যতিক্রম হ্যান্ডলিংটিই এটি করার উপায় -

try:
    line = raw_input()
    ... whatever needs to be done incase of no EOF ...
except EOFError:
    ... whatever needs to be done incase of EOF ...

উদাহরণ:

$ echo test | python -c "while True: print raw_input()"
test
Traceback (most recent call last):
  File "<string>", line 1, in <module> 
EOFError: EOF when reading a line

অথবা Ctrl-Zএকটি raw_input()প্রম্পটে টিপুন (উইন্ডোজ, Ctrl-Zলিনাক্স)


@ টেসেললেটিংহেকলার যা ডকুমেন্টেশন বলে না: "উত্থাপিত যখন কোনও বিল্ট-ইন ফাংশন (ইনপুট () বা কাঁচা-ইনপুট ()) কোনও ডেটা না পড়েই ফাইল-এর শেষ অবস্থানে (ইওএফ) আঘাত করে।"
টেডগ ম্যাকডোনাল্ড-জেনসেন

1
@ টেডজিএমসিডোনাল্ড-জেনসেন ভাল হেই, তাই হবে। কি অদ্ভুত. মিথ্যা দাবি প্রত্যাহার করা হয়েছে এবং অন্যায়ভাবে ডাউনভোট সরানো হয়েছে।
টেসেল্ল্যাটিংহেকলার

1

আপনি নিম্নলিখিত কোড স্নিপেট ব্যবহার করতে পারেন। রিডলাইনস () পুরো ফাইলটিতে একবারে পড়ে এবং লাইনে ভাগ করে দেয়।

line = obj.readlines()

0

@ ডাঃ এর দুর্দান্ত উত্তরের সাথে সাথে ওয়ালরাস অপারেটর (পাইথন> = 3.8) ব্যবহার করে সমতুল্য সমাধান:

with open(filename, 'rb') as f:
    while buf := f.read(max_size):
        process(buf)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.