Konvertieren Sie ein Python-Diktat in einen String und zurück

275

Ich schreibe ein Programm, das Daten in einem Wörterbuchobjekt speichert, aber diese Daten müssen irgendwann während der Programmausführung gespeichert und wieder in das Wörterbuchobjekt geladen werden, wenn das Programm erneut ausgeführt wird. Wie würde ich ein Wörterbuchobjekt in eine Zeichenfolge konvertieren, die in eine Datei geschrieben und wieder in ein Wörterbuchobjekt geladen werden kann? Dies wird hoffentlich Wörterbücher unterstützen, die Wörterbücher enthalten.

AJ00200
quelle

Antworten:

272

Das json-Modul ist hier eine gute Lösung. Es hat gegenüber pickle die Vorteile, dass es nur Klartextausgabe erzeugt und plattform- und versionübergreifend ist.

import json
json.dumps(dict)
Tyler Eaves
quelle
2
Ich werde mir auch dieses Modul ansehen. Sowohl json als auch pickle scheinen einfach zu bedienen zu sein, daher kommt es auf Dinge wie die plattformübergreifende Unterstützung an. Vielen Dank
AJ00200
5
Essiggurke wird an dieser Stelle eher als veraltet angesehen. Ich benutze json immer für solche Dinge. (Relativ) menschlich lesbar zu sein, ist die meiste Zeit ein GROSSES Plus.
Tyler Eaves
30
Sie sollten ein einfaches Beispiel hinzufügen, damit Benutzer sehen können, wie das geht.
Miguel Vazq
1
@TylerEaves Können Sie ein Beispiel dafür geben, wie es gemacht werden soll?
Boban
1
: Stirnrunzeln: Vergiss nicht, import jsonwie ich es getan habe!
Jesse Chisholm
207

Wenn Ihr Wörterbuch nicht zu groß ist, kann str + eval möglicherweise die Arbeit erledigen:

dict1 = {'one':1, 'two':2, 'three': {'three.1': 3.1, 'three.2': 3.2 }}
str1 = str(dict1)

dict2 = eval(str1)

print dict1==dict2

Sie können ast.literal_eval anstelle von eval verwenden, um zusätzliche Sicherheit zu gewährleisten, wenn die Quelle nicht vertrauenswürdig ist.

PabloG
quelle
13
Ich bin nicht wirklich bereit, mich mit den möglichen Exploits zu befassen, die dies in den Code einbringen könnte. Ich weiß nicht, welche Probleme json oder pickle haben könnten, aber ich weiß, dass eval in diesem Fall gefährlich wäre.
AJ00200
5
@ AJ00200: und die ast.literal_eval Alternative, die ich erwähnt habe?. In der Python-Hilfe: "Bewerten Sie einen Ausdrucksknoten oder eine Zeichenfolge, die einen Python-Ausdruck enthält, sicher. Die bereitgestellte Zeichenfolge oder der bereitgestellte Knoten besteht möglicherweise nur aus den folgenden Python-Literalstrukturen: Zeichenfolgen, Zahlen, Tupel, Listen, Diktate, Boolesche Werte und Keine. Dies kann zum sicheren Auswerten von Zeichenfolgen verwendet werden, die Python-Ausdrücke aus nicht vertrauenswürdigen Quellen enthalten, ohne dass die Werte selbst analysiert werden müssen. "
PabloG
Das scheint nützlich zu sein, aber als ich zuvor SQLite für die Verarbeitung dieser Daten verwendet habe und es über 1500 Einträge hatte, ist es ziemlich groß und wächst ständig.
AJ00200
164

Ich benutze json:

import json

# convert to string
input = json.dumps({'id': id })

# load to dict
my_dict = json.loads(input) 
Eyal Ch
quelle
14

Verwenden Sie das pickleModul, um es auf der Festplatte zu speichern und später zu laden.

ismail
quelle
2
@extraneon Eigentlich ist es eine Antwort auf die Frage. Es konvertiert es irgendwo in einen String und schreibt es in eine Datei. Ich muss nicht die eigentliche Konvertierung oder das Schreiben von Dateien durchführen, da alles von pickle gekapselt ist.
AJ00200
11

Warum nicht Python 3 des eingebauten verwenden ast Bibliothek Funktion literal_eval . Es ist besser, literal_eval anstelle von eval zu verwenden

import ast
str_of_dict = "{'key1': 'key1value', 'key2': 'key2value'}"
ast.literal_eval(str_of_dict)

gibt die Ausgabe als aktuelles Wörterbuch aus

{'key1': 'key1value', 'key2': 'key2value'}

Und wenn Sie ein Wörterbuch in einen String konvertieren möchten , verwenden Sie die str () -Methode von Python.

Angenommen, das Wörterbuch lautet:

my_dict = {'key1': 'key1value', 'key2': 'key2value'}

Und das wird so gemacht:

str(my_dict)

Wird drucken:

"{'key1': 'key1value', 'key2': 'key2value'}"

Dies ist das Einfache, wie Sie möchten.

FightWithCode
quelle
5

Wenn in Chinses

import codecs
fout = codecs.open("xxx.json", "w", "utf-8")
dict_to_json = json.dumps({'text':"中文"},ensure_ascii=False,indent=2)
fout.write(dict_to_json + '\n')
Beta
quelle
1
Dies wäre eine bessere Antwort, wenn Sie erklären würden, wie der von Ihnen bereitgestellte Code die Frage beantwortet.
pppery
4

Wörterbuch in JSON konvertieren (Zeichenfolge)

import json 

mydict = { "name" : "Don", 
          "surname" : "Mandol", 
          "age" : 43} 

result = json.dumps(mydict)

print(result[0:20])

Kriege dich:

{"name": "Don", "sur

String in Wörterbuch konvertieren

back_to_mydict = json.loads(result) 
Harvey
quelle
3

Ich denke, Sie sollten in Betracht ziehen, das shelveModul zu verwenden, das persistente dateibasierte wörterbuchähnliche Objekte bereitstellt. Es ist einfach anstelle eines "echten" Wörterbuchs zu verwenden, da es Ihrem Programm fast transparent etwas bietet, das genau wie ein Wörterbuch verwendet werden kann, ohne dass es explizit in eine Zeichenfolge konvertiert und dann in eine Datei (oder umgekehrt) geschrieben werden muss. umgekehrt).

Der Hauptunterschied besteht darin, dass Sie es zunächst open()vor der ersten Verwendung und dann nach Abschluss verwenden müssen close()(und möglicherweise sync()abhängig von der verwendeten writebackOption). Jedes "Regal" -Dateiobjekt, das erstellt wird, kann reguläre Wörterbücher als Werte enthalten, sodass sie logisch verschachtelt werden können.

Hier ist ein triviales Beispiel:

import shelve

shelf = shelve.open('mydata')  # open for reading and writing, creating if nec
shelf.update({'one':1, 'two':2, 'three': {'three.1': 3.1, 'three.2': 3.2 }})
shelf.close()

shelf = shelve.open('mydata')
print shelf
shelf.close()

Ausgabe:

{'three': {'three.1': 3.1, 'three.2': 3.2}, 'two': 2, 'one': 1}
Martineau
quelle
2

Wenn Sie sich für die Geschwindigkeit interessieren, verwenden Sie ujson (UltraJSON), das dieselbe API wie json hat:

import ujson
ujson.dumps([{"key": "value"}, 81, True])
# '[{"key":"value"},81,true]'
ujson.loads("""[{"key": "value"}, 81, true]""")
# [{u'key': u'value'}, 81, True]
Tomasz Bartkowiak
quelle
1

Ich benutze yaml dafür, wenn es lesbar sein muss (weder JSON noch XML sind das IMHO), oder wenn das Lesen nicht notwendig ist, benutze ich pickle.

Schreiben

from pickle import dumps, loads
x = dict(a=1, b=2)
y = dict(c = x, z=3)
res = dumps(y)
open('/var/tmp/dump.txt', 'w').write(res)

Lesen Sie zurück

from pickle import dumps, loads
rev = loads(open('/var/tmp/dump.txt').read())
print rev
Gerard
quelle
Sie sollten bFlag wirklich verwenden, wenn Sie die Datei hier öffnen.
Piotr Dobrogost
1
Ich hätte expliziter sein können. Der dumps()Standardwert ist jedoch Protokoll 0, bei dem es sich um ein ASCII-Protokoll handelt. Deshalb ist 'rb'IMHO nicht notwendig.
Gerard