পাইথনে আমি কীভাবে একটি ফাইল লাইন বাই লাইন পড়তে পারি?


137

প্রাক-timesতিহাসিক সময়ে (পাইথন ১.৪) আমরা করেছি:

fp = open('filename.txt')
while 1:
    line = fp.readline()
    if not line:
        break
    print line

পাইথন ২.১-এর পরে, আমরা করেছি:

for line in open('filename.txt').xreadlines():
    print line

পাইথন ২.৩-এ সুবিধাজনক পুনরায় প্রোটোকল পাওয়ার আগে এবং করতে পারলাম:

for line in open('filename.txt'):
    print line

আমি আরও ভার্বোস ব্যবহার করে কিছু উদাহরণ দেখেছি:

with open('filename.txt') as fp:
    for line in fp:
        print line

এটি কি পছন্দসই পদ্ধতিটি এগিয়ে চলছে?

[সম্পাদনা] আমি পেয়েছি যে বিবৃতি সহ ফাইলটি বন্ধ হওয়া নিশ্চিত করে ... তবে ফাইল আইটেমগুলির জন্য এটিরেটর প্রোটোকলটিতে কেন অন্তর্ভুক্ত নেই?


4
তবে, শেষের পরামর্শটি আগেরটির চেয়ে আর ভার্বোস নয়। এটি কেবল আরও কাজ করে (আপনার কাজ শেষ হলে ফাইলটি বন্ধ হয়ে যায় তা নিশ্চিত করে)।
আজরেই

1
@ আজ্রেই এটি আরও এক লাইন, সুতরাং উদ্দেশ্যমূলকভাবে এটি আরও ভার্জোজ।
thejjorn

7
আপনি যা বলছেন তা পেয়েছি তবে আমি কেবল আপেলের সাথে আপেলের তুলনা করছি বলছি, আপনার পোস্টের দ্বিতীয় সর্বশেষ পরামর্শটির ব্যতিক্রম হ্যান্ডলিং কোডও প্রয়োজন এবং শেষ বিকল্পটি কী করে তা মেলে। সুতরাং অনুশীলনে এটি আরও ভার্জোজ। আমার ধারণা এটি শেষ দুটি বিকল্পগুলির মধ্যে কোনটি সবচেয়ে ভাল, সেই প্রসঙ্গে নির্ভর করে।
আজরেই

উত্তর:


227

নিম্নলিখিতগুলিকে পছন্দ করার ঠিক এক কারণ রয়েছে:

with open('filename.txt') as fp:
    for line in fp:
        print line

আবর্জনা সংগ্রহের জন্য আমরা সিপিথনের অপেক্ষাকৃত নির্জনবাদী রেফারেন্স-কাউন্টিং স্কিম দ্বারা ক্ষতিগ্রস্থ হয়েছি। অন্য, পাইথনের অনুমানমূলক বাস্তবায়নগুলি withমেমরির দাবিদার করতে অন্য কোনও স্কিম ব্যবহার করে যদি অজানাভাবে "দ্রুত পর্যাপ্ত" ফাইলটি বন্ধ না করে ।

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

অথবা আপনি কেবল withব্লকটি ব্যবহার করতে পারেন ।

বোনাস প্রশ্ন

(যদি কেবল প্রশ্নের উদ্দেশ্যমূলক দিকগুলিতে আগ্রহী হন তবে এখনই পড়া বন্ধ করুন))

ফাইল আইটেমগুলির জন্য কেন এটিরেটর প্রোটোকলে অন্তর্ভুক্ত নেই?

এটি এপিআই ডিজাইন সম্পর্কে বিষয়গত প্রশ্ন, সুতরাং আমার দুটি অংশে বিষয়গত উত্তর রয়েছে।

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

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

প্রযুক্তিগত স্তরে, পাইথনের একটি ফাইল হ্যান্ডেল নিয়ে আপনি কিছু কাজ করতে চাইতে পারেন যা পুনরুক্তি ফাইল হ্যান্ডেলটি বন্ধ করে দিলে কাজ করবে না। উদাহরণস্বরূপ, ধরুন আমার দুবার ফাইলটি পুনরাবৃত্তি করতে হবে:

with open('filename.txt') as fp:
    for line in fp:
        ...
    fp.seek(0)
    for line in fp:
        ...

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

যৌগিকতা কোনও ভাষা বা এপিআইর অন্যতম গুরুত্বপূর্ণ ব্যবহারযোগ্যতা বৈশিষ্ট্য।


1
+1 কারণ এটি
অপ্টের

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

1
@ ডায়েটরিচএপ: সম্ভবত "ড্যাংলিং ফাইলের রেফারেন্স" সঠিক শব্দ ছিল না, আমি সত্যিকার অর্থে ফাইল হ্যান্ডলগুলি বোঝাতে চাইছি যা এখন অ্যাক্সেসযোগ্য ছিল না তবে এখনও বন্ধ হয়নি। যে কোনও ক্ষেত্রে, জিসি ফাইল হ্যান্ডেলটি বন্ধ করে দেবে যখন এটি ফাইল অবজেক্টটি সংগ্রহ করে, সুতরাং যতক্ষণ না আপনার কাছে ফাইলের অবজেক্টের অতিরিক্ত রেফারেন্স না থাকে এবং আপনি জিসি নিষ্ক্রিয় করেন না এবং আপনি দ্রুত অনেকগুলি ফাইল খুলছেন না উত্তরসূরি, আপনি ফাইলটি বন্ধ না করার কারণে "খুব বেশি ফাইল খোলা" হওয়ার সম্ভাবনা নেই।
মিথ্যা রায়ান

1
হ্যাঁ, "আমি যদি আপনার কোডটি অনাথ ফাইলের হাতলগুলিতে চূড়ান্ত কলকারীদের চূড়ান্ত কল করি তার চেয়ে দ্রুত যদি ফাইলগুলি খোলে" এর অর্থ হ'ল।
ডায়েটারিচ এপ্প

1
এর সাথে ব্যবহার করার বড় কারণ হ'ল আপনি যদি ফাইলটি বন্ধ না করেন তবে তা অবিলম্বে লেখা হবে না।
এন্টিমোনি

20

হ্যাঁ,

with open('filename.txt') as fp:
    for line in fp:
        print line

যাবার উপায়

এটি আরও ভারবস হয় না। এটি আরও নিরাপদ।


5

যদি আপনি অতিরিক্ত লাইন বন্ধ করে থাকেন তবে আপনি এর মতো একটি মোড়ক ফাংশনটি ব্যবহার করতে পারেন:

def with_iter(iterable):
    with iterable as iter:
        for item in iter:
            yield item

for line in with_iter(open('...')):
    ...

পাইথন ৩.৩-তে, yield fromবিবৃতিটি আরও ছোট করে তুলবে:

def with_iter(iterable):
    with iterable as iter:
        yield from iter

2
ফাংশনটি এক্সরেডলাইনসকে কল করুন .. এবং এটি xreadlines.py নামে একটি ফাইলে রাখুন এবং আমরা পাইথনটিতে ফিরে এসেছি 2.1 বাক্য গঠন :-)
thejjorn

@ থেজেজর্ন: সম্ভবত, তবে পাইথন ২.১ উদাহরণ যা আপনি উদ্ধৃত করেছেন সেটি বিকল্প বাস্তবায়নে অনাবৃত ফাইল হ্যান্ডলার থেকে নিরাপদ ছিল না। পাইথন ২.১ ফাইলের পড়া যা নিরবচ্ছিন্ন ফাইল হ্যান্ডলার থেকে নিরাপদ তা কমপক্ষে ৫ টি লাইন নেবে।
মিথ্যা রায়ান

-1
f = open('test.txt','r')
for line in f.xreadlines():
    print line
f.close()

5
এটি সত্যই প্রশ্নের উত্তর দেয় না
থায়নে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.