كيف أقوم بإزالة عروض الأسعار من مُهيئ فئة عند القراءة من ملف. بيثون

StackOverflow https://stackoverflow.com/questions/19825504

سؤال

أقوم بتخزين المكالمة لمهمة الفصل في صفيف في ملف .DAT. أرغب في قراءة هذا الملف وإعادة بناء مكالمات الفصل.

هذا هو الفصل الذي أستخدمه الآن:

class Task:

    def __init__(self, name, timespent):
        self.name = name
        self.timespent = timespent

    def __repr__(self):
        return repr('Task("%s",%s)'%(self.name, self.timespent))

ها هي القراءة من الملف:

task_list = []
with open("task_list2.dat", "r") as file:
    task_list = eval(file.readline())

ها هي الكتابة إلى الملف:

with open("task_list2.dat", "w") as outFile:
    print(repr(task_list), file = outFile)

وهنا محتويات الملف:['Task("class",20)']حيث "الفصل" هو اسم المهمة.

أفهم أن المشكلة تتعلق بالاقتباسات الفردية حول "المهمة" ("الفئة" ، 20) "، لكن ليس لدي أدنى فكرة عن كيفية التخلص منها. رسالة الخطأ التي أحصل عليها تقول شيئًا على غرار: "كائن STR ليس له سمة" اسم "

كيف يمكنني إزالة هذه الاقتباسات حتى أتمكن من إعادة بناء الفصول في المرة القادمة التي أقرأ فيها الملف؟

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

المحلول

أنت حقا ، حقا ، حقا لا تريد محاولة استخدام repr و eval كتنسيق التسلسل.

إذا استخدمت للتو ، قل ، pickle, ، لن يكون لديك هذه المشكلة على الإطلاق:

with open("task_list2.dat", "wb") as outFile:
    pickle.dump(task_list, outFile)

with open("task_list2.dat", "rb") as file:
    task_list = pickle.load(file)

أبسط بكثير ، نعم؟


ولكن إذا كنت تريد معرفة كيفية حل المشكلة الفورية بدلاً من جعله غير ذي صلة: لديك مشاكل متعددة في __repr__ الطريقة ، كلها تحتاج إلى إصلاح إذا كنت تريد أن تكون قابلة للتجزئة.

  • تقوم بإنشاء تمثيل سلسلة ... ثم اتصل repr عليه. تريد إرجاع تمثيل السلسلة ، وليس تمثيل سلسلة من تمثيل السلسلة. فقط اترك repr.
  • يجب عليك دائمًا تفويض repr من الكائنات الفرعية ، وليس str. إذا كنت تستخدم %- %r عوضا عن %s.
  • لا تحاول إضافة اقتباسات حول الأشياء. قد يحدث ذلك إذا كان الكائن نفسه لا يحتوي على علامات اقتباس ، وتراجع ، وشخصيات غير مرئية ، وما إلى ذلك ، ولكن لماذا تعتمد على ذلك؟ إذا كنت تعتقد أنك بحاجة إلى عروض أسعار ، فمن المؤتمر دائمًا أن تكون قد كسرت القاعدة السابقة ، ويجب عليك إصلاح ذلك بدلاً من ذلك.

إليك كيف يمكنك كتابة إعادة قابلية للتشغيل المستدير لهذا الفصل:

def __repr__(self):
    return 'Task(%r, %r)' % (self.name, self.timespent))

ويمكنك التحقق من أنه يفعل ما تريد:

>>> t = Task('task name', 23.4)
>>> t
Task('task name', 23.4)
>>> eval(repr(t))
Task('task name', 23.4)

بالطبع في مثالك الخاص ، فقط إصلاح المشكلة الأولى (إزالة الدعوة الزائفة إلى repr) كان من شأنه أن يتخلص من الاقتباسات الفردية وجعل هذا المثال الخاص يعمل. يمكنك أيضًا اختراق ذلك على الجانب القراءة عن طريق الاتصال eval مرتين. أو ، لهذا المثال بالذات ، حتى عن طريق الاتصال eval(s[1:-1]) أو eval(s.strip("'")). ولكن أي "إصلاح" من هذا القبيل سيجعل من الصعب تصحيح المشكلات العامة التي ستواجهها بمجرد أن تحصل ، على سبيل المثال ، اسم ليس بهذه البساطة مثل كلمة واحدة من حروف ASCII.

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