एक ताना लिखने के लिए txt फ़ाइल और इसे वापस पढ़ने?


115

मैं एक txt फ़ाइल में एक शब्दकोश लिखने की कोशिश कर रहा हूं। फिर कुंजी टाइप करके प्रमुख मान पढ़ें 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, p व्यक्ति वर्ग का उदाहरण होना चाहिए
— Avalal

जवाबों:


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बयान की आवश्यकता नहीं होती है क्योंकि अंतर्निहित "कचरा संग्रह" सुविधाओं से पता चलेगा कि आप फ़ाइल के साथ किए गए हैं और इसे आपके लिए बंद कर देंगे। लेकिन अन्य पायथन कार्यान्वयन, जैसे "ज्योथन" (जावा वीएम के लिए पायथन) या "PyPy" (सिर्फ-इन-कोड अनुकूलन के साथ वास्तव में अच्छा प्रायोगिक प्रणाली) आपके लिए फ़ाइल को बंद करने का पता नहीं लगा सकता है। इसका उपयोग करने की आदत डालना अच्छा है with, और मुझे लगता है कि यह कोड को समझने में बहुत आसान बनाता है।


dict()एक शब्दकोश या टुपल्स की सूची की अपेक्षा करता है। यह एक स्ट्रिंग का मूल्यांकन नहीं करेगा।
— ब्लेंडर

@ ब्लेंडर ओह, आप सही हैं और मैं थक गया हूं। मैं उत्तर संपादित करूँगा।
— स्टीवेहा

@ निक: इसे पहले चलाने का प्रयास करें;)
— ब्लेंडर

@ ब्लेंडर, हेड-अप के लिए धन्यवाद। और जब से मैं थक गया हूं मुझे लगता है कि मैं रात के लिए स्टैकऑवरफ्लो पर पोस्ट करना बंद कर दूंगा! :-)
— स्टीवेहा

175

क्या आपने जैसन मॉड्यूल की कोशिश की है ? JSON प्रारूप अजगर शब्दकोष के समान है। और यह मानव पठनीय / लेखन योग्य है:

>>> 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 (dict_x, indent = 4) जैसे कुछ का उपयोग करने का एक तरीका है? जब मैं आपके कोड का उपयोग करता हूं तो पूरा हुक्म एक पंक्ति में लिखा जाता है, चाहे वह कितना भी बड़ा क्यों न हो, और वह आसानी से मानव पठनीय नहीं होता है।
— हरटेलड्रियन

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इसके बजाय मॉड्यूल का उपयोग करें ।


नहीं, यह मुझे यह त्रुटि देता है फ़ाइल "name.py", पंक्ति 24, पढ़ने में प्रिंट कोड़ा [नाम] TypeError: स्ट्रिंग सूचक पूर्णांक होना चाहिए, मुझे नहीं लगा कि मैंने सोचा था कि p = व्यक्ति () ने इसे परिभाषित किया है
— Radioactive Head

वह पाठ आपके कोड में नहीं है। प्रश्न पूछने से पहले, समझाएं कि क्या गलत है।
— ब्लेंडर

2
पायथन ऑब्जेक्ट्स को फ़ाइलों में संग्रहीत करने के लिए, अचार मॉड्यूल का उपयोग करें जब तक कि ये फाइल को कॉन्फ़िगर न कर दें ताकि आप चाहते हैं कि वे मानव द्वारा संपादन योग्य हों - देखें कि अजगर और कॉन्फिग फाइलों से क्यों परेशान हैं?
— पियोट्र डोब्रोगोस्ट जूल

1
उत्तम। यह वही है जो मुझे चाहिए: एक फाइल में देशी अजगर संरचना राज्य को संग्रहीत करने के लिए जो उपयोगकर्ता संपादन योग्य नहीं है।
— बहमट

यह विधि जटिल शब्दकोशों के लिए पूरी तरह से काम करती है जैसा कि मैंने @KFL द्वारा सुझाए गए JSON पद्धति के लिए अपनी टिप्पणी में वर्णित किया है
— Gürol Canbek

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')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.