ফাইলটি টেক্সট করার জন্য একটি ডিক লিখে এবং এটি আবার পড়ছেন?


115

আমি একটি টেক্সট ফাইলে অভিধান লেখার চেষ্টা করছি। তারপরে কীগুলি টাইপ করে ডিক মানগুলি পড়ুন raw_input। আমার মনে হচ্ছে আমি কেবল একটি পদক্ষেপ মিস করছি তবে আমি এখন কিছুক্ষণ সন্ধান করছি।

আমি এই ত্রুটি পেয়েছি

File "name.py", line 24, in reading
    print whip[name]
TypeError: string indices must be integers, not str

আমার কোড:

#!/usr/bin/env python
from sys import exit

class Person(object):
    def __init__(self):
        self.name = ""
        self.address = ""
        self.phone = ""
        self.age = ""
        self.whip = {}

    def writing(self):
        self.whip[p.name] = p.age, p.address, p.phone
        target = open('deed.txt', 'a')
        target.write(str(self.whip))
        print self.whip

    def reading(self):
        self.whip = open('deed.txt', 'r').read()
        name = raw_input("> ")
        if name in self.whip:
            print self.whip[name]

p = Person()

while True:
    print "Type:\n\t*read to read data base\n\t*write to write to data base\n\t*exit to exit"
    action = raw_input("\n> ")
    if "write" in action:
        p.name = raw_input("Name?\n> ")
        p.phone = raw_input("Phone Number?\n> ")
        p.age = raw_input("Age?\n> ")
        p.address = raw_input("Address?\n>")
        p.writing()
    elif "read" in action:
        p.reading()
    elif "exit" in action:
        exit(0)

এই কোডটিতে সমস্যা কী?
ব্লেন্ডার

name 'p' is not defined, পি ব্যাক্তি শ্রেণির উদাহরণ হতে পারে
অ্যাভাসাল

উত্তর:


97

আপনার কোড প্রায় সঠিক ! আপনি ঠিক বলেছেন, আপনি কেবল একটি পদক্ষেপ মিস করছেন। আপনি যখন ফাইলটিতে পড়েন, আপনি এটি স্ট্রিং হিসাবে পড়ছেন; তবে আপনি স্ট্রিংটিকে অভিধানে পরিণত করতে চান।

আপনি যে ত্রুটি বার্তাটি দেখেছেন সেটি self.whipছিল একটি স্ট্রিং, অভিধান নয়।

আমি প্রথমে লিখেছিলাম যে আপনি কেবল স্ট্রিংটি খাওয়াতে পারেন dict()তবে এটি কার্যকর হয় না! আপনার অন্য কিছু করা দরকার।

উদাহরণ

এখানে সহজ উপায়: স্ট্রিংটি এ খাওয়ান eval()। তাই ভালো:

def reading(self):
    s = open('deed.txt', 'r').read()
    self.whip = eval(s)

আপনি এটি এক লাইনেই করতে পারেন, তবে আমার মনে হয় এটি এইভাবে অগোছালো দেখাচ্ছে:

def reading(self):
    self.whip = eval(open('deed.txt', 'r').read())

কিন্তু eval()কখনও কখনও সুপারিশ করা হয় না। সমস্যাটি হ'ল যে কোনও স্ট্রিংকে eval()মূল্যায়ন করবে এবং যদি কেউ আপনাকে সত্যই কৌতুকময় স্ট্রিং চালানোর জন্য প্রতারনা করে তবে খারাপ কিছু ঘটতে পারে। এই ক্ষেত্রে, আপনি কেবল নিজের ফাইলটি চালাচ্ছেন , সুতরাং এটি ঠিক হওয়া উচিত।eval()

তবে eval()দরকারী কারণ , কেউ এর বিকল্প তৈরি করেছেন এটি নিরাপদ। এটিকে বলা হয় literal_evalএবং এটি পাইথন মডিউল নামে পরিচিত ast

import ast

def reading(self):
    s = open('deed.txt', 'r').read()
    self.whip = ast.literal_eval(s)

ast.literal_eval() কেবলমাত্র পাইথন প্রকরণগুলিতে রূপান্তরিত স্ট্রিংগুলির মূল্যায়ন করবে, সুতরাং কোনও কৌতুকপূর্ণ স্ট্রিং আপনার কম্পিউটারে খারাপ কিছু করতে পারে এমন কোনও উপায় নেই।

সম্পাদনা

আসলে, পাইথনে সেরা অনুশীলন হ'ল withফাইলটি সঠিকভাবে বন্ধ হয়ে গেছে তা নিশ্চিত করার জন্য একটি বিবৃতি ব্যবহার করা । একটি withবিবৃতি ব্যবহার করতে উপরের পুনর্লিখন :

import ast

def reading(self):
    with open('deed.txt', 'r') as f:
        s = f.read()
        self.whip = ast.literal_eval(s)

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


dict()একটি অভিধান বা টিপলগুলির একটি তালিকা আশা করে। এটি কোনও স্ট্রিংকে মূল্যায়ন করবে না।
ব্লেন্ডার

@ ব্লেন্ডার ওহ, আপনি ঠিক বলেছেন এবং আমি ক্লান্ত হয়ে পড়েছি। আমি উত্তরটি সম্পাদনা করব।
স্টিভেহা

@ নিক: প্রথমে এটি চালানোর চেষ্টা করুন;)
ব্লেন্ডার

@ ব্লেন্ডার, মাথা উঁচু করার জন্য আপনাকে ধন্যবাদ। এবং যেহেতু আমি ক্লান্ত হয়ে পড়েছি মনে করি আমি রাতের জন্য স্ট্যাকওভারফ্লোতে পোস্ট করা বন্ধ করব! :-)
স্টিভেহা

175

আপনি কি জসন মডিউল চেষ্টা করেছেন ? জেএসওএন ফর্ম্যাটটি পাইথন অভিধানের সাথে খুব মিল। এবং এটি মানব পাঠযোগ্য / লিখনযোগ্য:

>>> import json
>>> d = {"one":1, "two":2}
>>> json.dump(d, open("text.txt",'w'))

এই কোডটি একটি পাঠ্য ফাইলে ডাম্প করে

$ cat text.txt 
{"two": 2, "one": 1}

এছাড়াও আপনি একটি JSON ফাইল থেকে লোড করতে পারেন:

>>> d2 = json.load(open("text.txt"))
>>> print d2
{u'two': 2, u'one': 1}

5
কোনও withবিবৃতিতে পড়ার / লেখার জন্য ফাইলটি খোলার পরে তা বন্ধ হয়ে যাওয়ার বিষয়টি নিশ্চিত করা উচিত?
ইকো

2
বাহ, এটি খুব সুন্দর।
zx1986

3
কিছু জটিল অভিধানে যেমন পদ্ধতিতে নেস্টেড মান রয়েছে (যেমন d = {"one": {"1" : 1, "a": {"i"}}}) তে এই পদ্ধতিটি ব্যবহার করে আমি সমস্যার মুখোমুখি হয়েছি । অতএব, আমি @ ব্লেন্ডারের আচার পদ্ধতিটি প্রস্তাব করি যা আমার ক্ষেত্রে কার্যকর।
গারোল ক্যানবেক

1
নোট করুন যে পাইথনের জসন json.dump করার সময় ডার কীগুলি স্ট্রিংগুলিতে অনুবাদ করে , তাই json.load করার json.dump({1: 'one'}, file)সময় আবার পড়তে হবে {'1': 'one'}। আপনি পাইথন বাদে অন্য ভাষা ব্যবহার করে সেভ করা ফাইলটি পড়তে না পারলে আচার ব্যবহার করা ভাল।
পিল

ডেস্কটি আরও সুস্পষ্ট করার জন্য ফাইলটিতে যেভাবে ডিকটি লেখা হচ্ছে তা ফর্ম্যাট করার জন্য json.dumps (ডিক_এক্স, ইনডেন্ট = 4) এর মতো কিছু ব্যবহার করার কি উপায় আছে? আমি যখন আপনার কোডটি ব্যবহার করি তখন পুরো ডিকটি এক লাইনে লেখা থাকে, এটি যত বড় হোক না কেন, এবং এটি সহজেই মানুষের পঠনযোগ্য নয়।
herteladrian

70

ফাইলগুলিতে পাইথন অবজেক্টগুলি সঞ্চয় করতে pickleমডিউলটি ব্যবহার করুন :

import pickle

a = {
  'a': 1,
  'b': 2
}

with open('file.txt', 'wb') as handle:
  pickle.dump(a, handle)

with open('file.txt', 'rb') as handle:
  b = pickle.loads(handle.read())

print a == b # True

লক্ষ্য করুন যে আমি কখনও সেট করি নি b = a, তবে পরিবর্তে aকোনও ফাইলকে বেছে নিয়েছি এবং তারপরে এটিকে পিকযুক্ত করে ফেলেছি b

আপনার ত্রুটি হিসাবে:

self.whip = open('deed.txt', 'r').read()

self.whipঅভিধান অভিধান ছিল। deed.txtটেক্সট রয়েছে, সুতরাং যখন আপনি বিষয়বস্তু লোড deed.txtমধ্যে self.whip, self.whipহয়ে স্ট্রিং নিজেই উপস্থাপনা।

আপনি সম্ভবত একটি পাইথন অবজেক্টে স্ট্রিংটি আবার মূল্যায়ন করতে চান:

self.whip = eval(open('deed.txt', 'r').read())

কেমন evalশোনাচ্ছে তা লক্ষ্য করুন evil। এটা ইচ্ছাকৃত। ব্যবহার করুন pickleপরিবর্তে মডিউল।


না এটি আমাকে এই ত্রুটিটি ফাইল "নাম.পি" দেয়, লাইন 24, প্রিন্ট হুইপ পড়ার ক্ষেত্রে [নাম] টাইপ এরর: স্ট্রিং সূচকগুলি অবশ্যই পূর্ণসংখ্যার হতে হবে, আমি ভেবেছি পি = ব্যক্তি () এটি সংজ্ঞায়িত করা হয়নি
রেডিওএকটিভ হেড

এই পাঠ্যটি আপনার কোডে নেই। একটি প্রশ্ন জিজ্ঞাসার আগে, কী ভুল তা ব্যাখ্যা করুন।
ব্লেন্ডার

2
পাইথন অবজেক্টগুলিকে ফাইলগুলিতে সঞ্চয় করতে, আচার মডিউলটি ব্যবহার করুন যদি না এগুলি কনফিগার করা ফাইল না থাকে তবে আপনি চান না সেগুলি মানুষের দ্বারা সম্পাদনযোগ্য হতে পারে - কেন পাইথন এবং কনফিগার ফাইলগুলি নিয়ে বিরক্ত হন?
পাইওটর ডব্রোগস্ট

1
পারফেক্ট। আমার ঠিক এটির দরকার: একটি ফাইলে দেশীয় অজগর কাঠামোর অবস্থা সঞ্চয় করতে যা ব্যবহারকারীর সম্পাদনযোগ্য নয়।
বাহামা

এই পদ্ধতিটি জটিল অভিধানগুলির জন্য নিখুঁতভাবে কাজ করে যেমন আমি
@KFL- এর

8

আমি আমার নিজস্ব ফাংশন তৈরি করেছি যা সত্যই সুন্দরভাবে কাজ করে:

def writeDict(dict, filename, sep):
    with open(filename, "a") as f:
        for i in dict.keys():            
            f.write(i + " " + sep.join([str(x) for x in dict[i]]) + "\n")

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

def readDict(filename, sep):
    with open(filename, "r") as f:
        dict = {}
        for line in f:
            values = line.split(sep)
            dict[values[0]] = {int(x) for x in values[1:len(values)]}
        return(dict)

আপনার মানগুলি দীর্ঘ না হলে দুর্দান্ত কোড। আমার অভিধানে একাধিক দীর্ঘ স্ট্রিং অন্তর্ভুক্ত রয়েছে যা সবেমাত্র '...' দিয়ে কাটা হয়েছে
অ্যানি

7

হাই, অভিধান লিখতে ও পড়ার একটি উপায় রয়েছে আপনি নিজের অভিধানটি JSON ফর্ম্যাটে পরিণত করতে পারেন এবং পড়তে এবং দ্রুত লিখতে পারেন কেবল এটি করুন:

করার লিখতে আপনার তারিখ:

 import json

 your_dictionary = {"some_date" : "date"}
 f = open('destFile.txt', 'w+')
 f.write(json.dumps(your_dictionary))

এবং আপনার ডেটা পড়তে :

 import json

 f = open('destFile.txt', 'r')
 your_dictionary = json.loads(f.read())

6

আপনি কী-মান জুটির মাধ্যমে পুনরাবৃত্তি করতে পারেন এবং এটি ফাইলটিতে লিখতে পারেন

pair = {'name': name,'location': location}
with open('F:\\twitter.json', 'a') as f:
     f.writelines('{}:{}'.format(k,v) for k, v in pair.items())
     f.write('\n')
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.