2017-02-03 5 views
0

Gibt es eine Möglichkeit, Python eval() und/oder zu verwenden, um den Status zwischen Programmläufen zu erhalten, ohne Daten in eine Datei oder Datenbank zu schreiben. Hier ist die Frage genauer. Ich möchte ein Programm schreiben, das eine Zahl ausgibt und dann jedes Mal, wenn es erneut ausgeführt wird, 1 zu sich selbst addiert, ohne eine Variable in einer Datei oder Datenbank zu speichern. Ich habe diese Frage kürzlich in einem Interview gefragt. Jede Hilfe wird geschätzt.Python eval() und exec()

+0

Nr Warum würden Sie denken, denen Sie helfen würde? 'eval' und' exec' haben keinen magischen persistenten Speicher, der ihnen zugeordnet ist. – user2357112

+0

Hat der Interviewer speziell gefragt, wie dies mit eval und exec zu tun ist, oder hat er nur gefragt, wie man den Zustand im Allgemeinen halten kann, und Sie kamen auf die Idee, eval/exec selbst zu benutzen? – Kevin

+0

Das war Teil des Hinweises, der mir während des Interviews gegeben wurde. Anscheinend kann eval irgendwie benutzt werden, um Code selbst zu modifizieren, was ich nicht weiß wie. – Stacker

Antwort

1

Haftungsausschluss: Ich mache nicht empfehlen, dies zu tun. 99,999% der Zeit ist es besser, serialisierbare Informationen in einer eigenen Datei zu speichern.

Wenn von „ohne Schreiben in eine Datei Daten“, meinen Sie „ohne Daten zu seine eigenen Datei zu schreiben“, Sie die Python-Datei öffnen können, die und schreiben die Daten an Ort und Stelle ausgeführt wird:

import re 

x = 0 
print "The value of the variable x is: {}".format(x) 

with open("test.py") as file: 
    data = file.read() 

data = re.sub(r"x = (\d+)", "x = {}".format(x+1), data) 

with open("test.py", "w") as file: 
    file.write(data) 

Jetzt ändert sich der Wert mit jeder weiteren Ausführung.

C:\Users\Kevin\Desktop>test.py 
The value of the variable x is: 0 

C:\Users\Kevin\Desktop>test.py 
The value of the variable x is: 1 

C:\Users\Kevin\Desktop>test.py 
The value of the variable x is: 2 

C:\Users\Kevin\Desktop>test.py 
The value of the variable x is: 3 

C:\Users\Kevin\Desktop>test.py 
The value of the variable x is: 4 

Aber auch hier ist es vorzuziehen, die Daten in einer separaten Datei zu halten einfach, zum Beispiel mit shelve:

import shelve 

d = shelve.open("data.dat") 
if "x" not in d: 
    d["x"] = 0 

print "The value of x is: {}".format(d["x"]) 
d["x"] += 1 

Oder vielleicht json, wenn Sie Menschen Lesbarkeit Wert:

import json 

try: 
    with open("data.dat") as file: 
     d = json.load(file) 
except IOError: #first execution. file doesn't exist yet. 
    d = {"x":0} 

print "The value of x is: {}".format(d["x"]) 
d["x"] += 1 

with open("data.dat", "w") as file: 
    json.dump(d, file) 

Oder sogar eine vollwertige Datenbank, wenn Sie eine Menge Daten haben.

+0

Nun, das ist hervorragend Ich denke, die erste Option ist, was der Interviewer im Sinn hatte. Es ist verschachtelt, aber es ist immer noch eine Lösung. – Stacker

1

Dies sollte idealerweise Code-Golf sein, aber es hat Spaß gemacht!
Hier ist eine Lösung mit exec und eval wie gewünscht.
Der Code ist 15 Zeilen lang, bei jedem Durchlauf eine zusätzliche Zeile zum (z=1) Py Datei hinzugefügt wird
und, was gedruckt wird, ist number of lines in file now - 15, wodurch Druck Inkrementen bei jedem Durchlauf

initial_num_lines = 15 
def get_lines_in_file(): 
    f = open('evalexec.py', 'r') 
    num_lines = len(f.readlines()) 
    return num_lines 

lines = str(get_lines_in_file() - initial_num_lines) 
print eval(lines+'+1') 
exec_code = ''' 
f = open('evalexec.py', 'a') 
f.write("\\nz=1") 
f.close() 
''' 
exec(exec_code) 

OUTPUT:


>python evalexec.py 
0 

>python evalexec.py 
1 

>python evalexec.py 
2 

>python evalexec.py 
3 
+0

Ah schön. Ich schätze, das kommt mir am nächsten. – Stacker

1

Sie die Datei verwenden können stats Spur des letzten geänderten Wert zu halten (was eine ganze Zahl), und aktualisieren Sie es jeden Lauf mit os.utime:

import os 

last_modified = os.stats(__file__).st_mtime 
print(int(last_modified)) 

os.utime(__file__, (last_modified, last_modified + 1)) 

aufeinanderfolgende Durchläufe:

Petes-Mac:~ petewood$ python inc.py 
1486149574 
Petes-Mac:~ petewood$ python inc.py 
1486149575 
Petes-Mac:~ petewood$ python inc.py 
1486149576