2016-09-22 5 views
2

Wie kann ich ein Python-Skript selbst ändern?Wie kann ich ein Python-Skript selbst ändern?

Um es einkochen, ich möchte ein Python-Skript haben (run.py) wie folgt

a = 0 
b = 1 
print a + b 
# do something here such that the first line of this script reads a = 1 

Derart, dass das nächste Mal das Skript ausgeführt wird würde es aussehen

a = 1 
b = 1 
print a + b 
# do something here such that the first line of this script reads a = 2 

Ist das ist irgendwie möglich? Das Skript verwendet möglicherweise externe Ressourcen. Allerdings sollte alles funktionieren, indem Sie einfach die eine run.py -Datei ausführen.

EDIT: Es war vielleicht nicht klar genug, aber das Skript sollte sich selbst aktualisieren, keine andere Datei. Sicher, sobald Sie eine einfache Konfigurationsdatei neben dem Skript zulassen, ist diese Aufgabe trivial.

Antwort:

Es ist eigentlich viel einfacher als gedacht. @Khelwoods Vorschlag funktioniert gut, das Skript zu öffnen und seinen eigenen Inhalt zu schreiben, ist völlig unproblematisch. @ Gerrats Lösung funktioniert auch gut. Dies ist, wie ich es habe:

# -*- coding: utf-8 -*- 
a = 0 
b = 1 
print a + b 

content = [] 
with open(__file__,"r") as f: 
    for line in f: 
     content.append(line) 

with open(__file__,"w") as f: 
    content[1] = "a = {n}\n".format(n=b) 
    content[2] = "b = {n}\n".format(n=a+b) 
    for i in range(len(content)): 
     f.write(content[i]) 
+0

Ja, es ist möglich. Tatsächlich gibt es mehrere Möglichkeiten, dieses Ziel zu erreichen. –

+0

Ja, es ist möglich, aber warum? – Jaco

+1

Sie können Ihr Skript mit 'open ('run.py', 'w') ... öffnen und Änderungen daran vornehmen, wenn Sie das möchten. Ist das alles, was du wissen wolltest? – khelwood

Antwort

3

Ein Beispiel (der Wert von a jedes Mal seinen Lauf zu ändern):

a = 0 
b = 1 
print a + b 

with open(__file__, 'r') as f: 
    lines = f.read().split('\n') 
    val = int(lines[0].split(' = ')[-1]) 
    new_line = 'a = {}'.format(val+1) 
    new_file = '\n'.join([new_line] + lines[1:]) 

with open(__file__, 'w') as f: 
    f.write('\n'.join([new_line] + lines[1:])) 
-1

eine Datei a.txt machen, dass ein Zeichen in einer Zeile enthält:

0 

dann in Ihrem Skript, dass die Datei öffnen und den Wert abrufen, dann sofort ändern:

with open('a.txt') as f: 
    a = int(f.read()) 
with open('a.txt', 'w') as output: 
    output.write(str(a+1)) 
b = 1 
print a+b 

Beim ersten Start des Programms wird a0, und die Datei wird so geändert, dass sie eine 1 enthält. Bei nachfolgenden Läufen wird a weiterhin jedes Mal um 1 erhöht.

0

Was Sie fordern, würde erfordern, dass Sie Dateien auf der Ebene {sys} bearbeiten. Im Grunde würden Sie die aktuelle Datei einlesen, ändern, überschreiben und das aktuelle Modul neu laden. Ich habe kurz damit gespielt, weil ich neugierig war, aber ich habe Probleme mit Dateisperrung und Dateizugriff bekommen. Das sind wahrscheinlich lösbar, aber ich vermute, dass dies nicht wirklich das ist, was Sie hier wollen.

Zuerst: erkennen, dass es im Allgemeinen eine gute Idee ist, eine Trennung zwischen Code und Daten aufrechtzuerhalten. Es gibt Ausnahmen, aber für die meisten Zwecke sollten Sie die Teile Ihres Programms, die zur Laufzeit wechseln können, dazu bringen, ihre Konfiguration aus einer Datei zu lesen und Änderungen in diese Datei zu schreiben.

Zweitens: idomatically, die meisten Python-Projekte verwenden YAML für die Konfiguration

Hier ist ein einfaches Skript, das die yaml Bibliothek verwendet aus einer Datei ‚config aufgerufen zu lesen.yaml‘und erhöht den Wert von 'a' jedes Mal das Programm ausgeführt wird:

#!/usr/bin/python 
import yaml 

config_vals = "" 
with open("config.yaml", "r") as cr: 
    config_vals = yaml.load(cr) 

a = config_vals['a'] 
b = config_vals['b'] 
print a + b 

config_vals['a'] = a + 1 
with open("config.yaml", "w") as cw: 
    yaml.dump(config_vals, cw, default_flow_style=True) 

Die Runtime-Ausgabe wie folgt aussieht:

$ ./run.py 
3 
$ ./run.py 
4 
$ ./run.py 
5 

Die anfängliche YAML-Konfigurationsdatei sieht wie folgt aus:

a: 1 
b: 2 
+0

Eigentlich ist das, was Sie im ersten Absatz beschreiben, genau das, was ich will. – ImportanceOfBeingErnest

Verwandte Themen