سؤال

وأحاول استخراج مجموعة من الخطوط من ملف CSV وكتابتها إلى آخر، ولكن أواجه بعض المشاكل.

import csv

f = open("my_csv_file.csv", "r")
r = csv.DictReader(f, delimiter=',')
fieldnames = r.fieldnames

target = open("united.csv", 'w')
w = csv.DictWriter(united, fieldnames=fieldnames)

while True:
try:
    row = r.next()
    if r.line_num <= 2: #first two rows don't matter
        continue
    else:
        w.writerow(row)

except StopIteration:
    break

f.close()
target.close()

وتشغيل هذا، وأحصل على الخطأ التالي:

Traceback (most recent call last):
File "unify.py", line 16, in <module>
    w.writerow(row)
File "C:\Program Files\Python25\lib\csv.py", line 12
    return self.writer.writerow(self._dict_to_list(row
File "C:\Program Files\Python25\lib\csv.py", line 12
    if k not in self.fieldnames:
TypeError: argument of type 'NoneType' is not iterable

ولست متأكدا تماما ما أنا دونغ خطأ.

هل كانت مفيدة؟

المحلول

وأنا لا أعرف سواء، ولكن منذ كل ما نقوم به هو نسخ الخطوط من ملف واحد إلى آخر لماذا يكلف نفسه عناء مع الاشياء csv على الإطلاق؟ لماذا لا شيء من هذا القبيل:

f = open("my_csv_file.csv", "r")
target = open("united.csv", 'w')

f.readline()
f.readline()
for line in f:
    target.write(line)

نصائح أخرى

لإزالة هذا اللبس حول الخطأ: تحصل عليه بسبب تعيين r.fieldnames فقط مرة واحدة تقرأ من ملف الإدخال لأول مرة باستخدام r. وبالتالي الطريقة التي كتب عليه، وسوف يكون دائما تهيئة fieldnames إلى None.

يمكنك تهيئة w = csv.DictWriter(united, fieldnames=fieldnames) مع r.fieldnames فقط بعد قراءة السطر الأول من r، مما يعني أنك لن تضطر إلى إعادة هيكلة التعليمات البرمجية.

ويتم توثيق هذا السلوك في بيثون مكتبة ستاندرد الوثائق

<اقتباس فقرة>   

التحف DictReader لها السمة العامة التالية:

     

وcsvreader.fieldnames

     

إذا لم يتم تمرير كمعلمة عند إنشاء الكائن، تتم تهيئة هذه السمة على الوصول الأول أو عند قراءة السجل الأول من الملف.

وأما بالنسبة للاستثناء، يبدو هذا السطر:

w = csv.DictWriter(united, fieldnames=fieldnames)

يجب أن يكون

w = csv.DictWriter(target, fieldnames=fieldnames)

والسبب انك تحصل على الخطأ هو الأكثر احتمالا أن ملف CSV الأصلي (my_csv_file.csv) لايوجد صف الرأس. لذلك، عند بناء الكائن القارئ، يتم تعيين الحقل fieldnames لNone.

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top