بيثون CSV DictReader / القضايا الكاتب
سؤال
وأحاول استخراج مجموعة من الخطوط من ملف 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 اسم المفتاح يطرح استثناء.