python open - الطريقة الصحيحة لكتابة خط للملف؟




file in (8)

في Python 3 هي وظيفة ، ولكن في Python 2 يمكنك إضافة هذا إلى أعلى الملف المصدر:

from __future__ import print_function

ثم تفعل

print("hi there", file=f)

اعتدت القيام print >>f, "hi there"

ومع ذلك ، يبدو أن print >> يتم إهمالها. ما هي الطريقة الموصى بها لتنفيذ السطر أعلاه؟

تحديث : فيما يتعلق بكل هذه الإجابات مع "\n" ... هل هذا عالمي أم خاص بـ Unix؟ IE ، هل يجب أن أفعل "\r\n" على نظام Windows؟


عندما قلت الخط ، فهذا يعني أن بعض الأحرف المسلسلة تنتهي إلى \ n. يجب أن يكون الخط آخر في مرحلة ما ، لذا يجب أن نضع في الاعتبار "\ n" في نهاية كل سطر. هنا هو الحل:

with open('YOURFILE.txt', 'a') as the_file:
    the_file.write('Hello')

في وضع الإلحاق بعد كل كتابة ، ينتقل المؤشر إلى السطر الجديد ، إذا كنت تريد استخدام وضع "w" ، يجب إضافة أحرف "\ n" في نهاية دالة write ():

the_file.write('Hello'+'\n')

يجب عليك استخدام وظيفة print() المتوفرة منذ Python 2.6+

from __future__ import print_function  # Only needed for Python 2
print("hi there", file=f)

بالنسبة إلى Python 3 ، لا تحتاج إلى import ، نظرًا لأن وظيفة print() هي الإعداد الافتراضي.

البديل سيكون استخدام:

f = open('myfile', 'w')
f.write('hi there\n')  # python will convert \n to os.linesep
f.close()  # you can omit in most cases as the destructor will call it

نقلا عن وثائق بيثون بخصوص الخطوط الجديدة:

في المخرجات ، إذا كان السطر الجديد os.linesep ، os.linesep ترجمة أي أحرف مكتوبة إلى '\n' سطر النظام الافتراضي ، os.linesep . إذا كان newline هو '' ، فلن تتم الترجمة. إذا كان newline هو أي من القيم القانونية الأخرى ، يتم ترجمة أي أحرف مكتوبة إلى السلسلة المحددة.


يجب أن يكون هذا بسيطًا كما يلي:

with open('somefile.txt', 'a') as the_file:
    the_file.write('Hello\n')

من التوثيق:

لا تستخدم os.linesep سطر عند كتابة الملفات المفتوحة في وضع النص (الافتراضي) ؛ استخدم "\ n" واحدة بدلاً من ذلك ، على جميع الأنظمة الأساسية.

بعض القراءة المفيدة:


إذا كنت تكتب الكثير من البيانات والسرعة هي مصدر قلق يجب أن تذهب مع f.write(...) . لقد قمت بإجراء مقارنة سريعة للسرعة وكانت أسرع بكثير من print(..., file=f) عند إجراء عدد كبير من عمليات الكتابة.

import time    

start = start = time.time()
with open("test.txt", 'w') as f:
    for i in range(10000000):
        # print('This is a speed test', file=f)
        # f.write('This is a speed test\n')
end = time.time()
print(end - start)

في المتوسط ​​، تم الانتهاء من write في جهاز 2.45 على الجهاز ، في حين استغرق print حوالي 4 مرات (9.76 ثانية). ومع ذلك ، في معظم سيناريوهات العالم الواقعي ، لن تكون هذه مشكلة.

إذا اخترت الذهاب print(..., file=f) ، فربما ستجد أنك ستحتاج إلى منع الخط الجديد من وقت لآخر ، أو استبداله بشيء آخر. ويمكن القيام بذلك عن طريق تحديد معلمة end الاختيارية ، على سبيل المثال ؛

with open("test", 'w') as f:
    print('Foo1,', file=f, end='')
    print('Foo2,', file=f, end='')
    print('Foo3', file=f)

أيًا كانت الطريقة التي تختارها ، فأنا أقترح عليك استخدام with ذلك لأنها تجعل التعليمة البرمجية أسهل للقراءة.

تحديث : يفسر هذا الاختلاف في الأداء بحقيقة أن write مخزنة بشكل كبير وتعود قبل أن تتم الكتابة إلى القرص بالفعل (انظر هذه الإجابة ) ، بينما تستخدم print (على الأرجح) التخزين المؤقت للخط. سيكون الاختبار البسيط لهذا هو التحقق من الأداء للكتابة الطويلة أيضاً ، حيث تكون المساوئ (من حيث السرعة) لتدبير الخط أقل وضوحاً.

start = start = time.time()
long_line = 'This is a speed test' * 100
with open("test.txt", 'w') as f:
    for i in range(1000000):
        # print(long_line, file=f)
        # f.write(long_line + '\n')
end = time.time()

print(end - start, "s")

ويصبح الفرق في الأداء الآن أقل وضوحًا بكثير ، مع متوسط ​​وقت قدره 2.20 ثانية write و 3.10 ثانية print . إذا كنت بحاجة إلى تجميع مجموعة من السلاسل للحصول على أداء خط loooong هذا ، فستكون حالات الاستخدام حيث تكون print أكثر كفاءة نادرة بعض الشيء.


فيما يتعلق os.linesep:

فيما يلي جلسة لمترجم فوري بلغة Python 2.7.1 غير محررة على نظام Windows:

Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.linesep
'\r\n'
>>> f = open('myfile','w')
>>> f.write('hi there\n')
>>> f.write('hi there' + os.linesep) # same result as previous line ?????????
>>> f.close()
>>> open('myfile', 'rb').read()
'hi there\r\nhi there\r\r\n'
>>>

على نظام التشغيل Windows:

كما هو متوقع ، لا ينتج os.linesep نفس النتيجة مثل '\n' . لا توجد طريقة يمكن أن تنتج نفس النتيجة. 'hi there' + os.linesep مساوية لـ 'hi there\r\n' ، والتي لا تعادل 'hi there\n' .

الأمر بسيط: استخدم \n التي سيتم ترجمتها تلقائيًا إلى os.linesep. ولقد كان بهذه البساطة منذ أول ميناء لبيثون إلى ويندوز.

ليس هناك فائدة من استخدام os.linesep على أنظمة غير Windows ، وينتج نتائج خاطئة على Windows.

لا تستخدم os.linesep!


لا أعتقد أن هناك طريقة "صحيحة".

سأستخدم:

with open ('myfile', 'a') as f: f.write ('hi there\n')

في ذكرى تيم توادي .


أوضحت الإجابات الأخرى ذلك جيدًا بالفعل ، ولكني أرغب في تقديم تجربة أخرى توضح طبيعة كائنات النطاق:

>>> r = range(5)
>>> for i in r:
        print(i, 2 in r, list(r))

0 True [0, 1, 2, 3, 4]
1 True [0, 1, 2, 3, 4]
2 True [0, 1, 2, 3, 4]
3 True [0, 1, 2, 3, 4]
4 True [0, 1, 2, 3, 4]

كما ترى ، فإن كائن النطاق هو كائن يتذكر نطاقه ويمكن استخدامه عدة مرات (حتى أثناء التكرار فوقه) ، وليس مجرد مولد لمرة واحدة.





python file-io