Variablenwerte mit einer txt.Datei in Python Skript einfügen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

Hallo Jungs,

ich bin seit kurzem neu mit Python unterwegs. Die ersten Schritte haben Dank Tutorials und den Foren funktioniert. Nun gehts nicht weiter...
Ich möchte folgendes umsetzten:

Ich habe ein Python Script, welches veränderliche Variablen enthalten soll. Dieses Python Script ist fertig und funktioniert mit Zahlenwerte. Nun ersetzte ich die Zahlenwerte mit Variablen. Diese sollen wiederum in einer Textdatei definiert werden (var1 = 1 ; var2 = 3; var3=HP35 usw.). Nun möchte ich das meine Variablen in mein Python Script geladen werden und dort die Stellen der Platzhalter (var1, var2, var3) einnehmen. Das ursprüngliche Script soll dabei aber nicht überspeichert werden, sondern nur als Vorlage benutzt werden, sodass ich eine "neues" Python Script erhalte, welches unter einem neuen Namen(Typenbezeichnung: HP35 o.ä.) abgespeichert wird.
Zusammenfassend:
Python Script mit Variablen und Textdatei mit Definitionen der Variablen sollen zu einem neuen Python Script inklusive der Variablenwerte verschmelzen.

Meine Idee bisher:

Code: Alles auswählen

fobj_in = open("Variableneingabe.txt")
fobj_out = open("neues_script.py","w")
i = 1
for line in fobj_in:
    print line.rstrip()
    fobj_out.write("python sc: " + line)
    i = i + 1
fobj_in.close()
fobj_out.close()
Hier komme ich nicht weiter und habe den Verdacht, dass ich auf dem falschen Weg bin. Falls die Frage schon beantwortet wurde, würde ich mich über einen Hinweis freuen.
Wenn dies noch nicht der Fall ist, würde ich mich über Anregungen sehr freuen. :D

Daher bedanke ich mich im Voraus.

Lena

P.S.: Falls der Fehler nicht genau genug beschrieben ist, fragt nach. Dann werde ich das versuchen genauer zu beschreiben.
Zuletzt geändert von Anonymous am Donnerstag 24. Juli 2014, 15:51, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@lena_92: Quelltext generieren ist in der Regel eine unschöne Lösung. Man würde eher ein Skript schreiben das die Werte aus einer Datei lädt und den Namen dieser Datei als Argument übergeben bekommt. Für die Werte in der Datei würde sich ein verbreitetes Format eignen, wie eine INI-Datei oder JSON. Für beides gibt es etwas in der Python-Standardbibliothek (`ConfigParser`, `json`). Zum Verarbeiten von Kommandozeilenargumenten und Optionen gibt es das `argparse`-Modul.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Auch wenn BlackJack Dir schon das Vorgehen in diesem Anwendungsfall beschrieben hat, hier noch mal die Anmerkung, dass man ansonsten für die Manipulation von Strings eine Template-Engine nutzen sollte. Dies kann bei einfachen Sachen ruhig die in der Standard-Lib mitgelieferte sein, ansonsten eben ein externes Modul, wie die exzellente Jinja2 Template-Engine.

Um es noch einmal klar zu sagen: In Deinem Falle würde man die *Daten* in einer separaten Datendatei serialisieren, wie eben mittels JSON o.ä.. "Templating" nutzt man wirklich nur für die Generierung von dynamischen "Texten", wie eben HTML-Seiten (oder auch anderen textbasierten Eingabedaten; ich habe jinja z.B. mal für PovRay-Dateien benutzt).
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

Vielen Dank für die Informationen. Ich werde die Tipps versuchen anzuwenden.
Schönen Tag! 8)
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

Hallo zusammen,

danke nochmals für die Tipps.
Ich habe nun eine .cfg Datei mit meinem Variablen und lade diese in mein Hauptdokument.
Dann öffne ich eine weitere Datei um mein Script mit den veränderten Variablen da drin zu speichern, siehe Code.

Code: Alles auswählen

#!/usr/bin/python

import ConfigParser
import ast

#Variablen werden geladen
config = ConfigParser.RawConfigParser()
config.read('example.cfg')


datei = open("Test_2.py" ,"w" )
datei.write(

	"Diese Fuktion "  +config.get('section1', 'var1')+  " ist cool! Aber was kann man dazu noch sagen. \n"
             "Eine weitere Zeile. \n"

Nun füge ich aber das ganze Script ein und muss, damit in der Outputdatei alles geordnet ist, überall Anführungszeichen und Zeilenumbrüche manuell angeben. Ich habe nach Befehlübergaben gesucht, sodass "datei.write" dies automatisch macht.

Gibt es so etwas? Oder kann ich

Code: Alles auswählen

	"Diese Fuktion "  +config.get('section1', 'var1')+  " ist cool! Aber was kann man dazu noch sagen. \n"
             "Eine weitere Zeile. \n"
durch eine externe Datei wieder laden lassen. Hierbei müssen aber die Variablen veränderbar bleiben. Das wäre ein süßes Add on.

Im Moment würde ich gerne einen Befehl einfügen, der alles Zeilenweise wieder einfügt und alle Zeilen in Anführungszeichen schreibt.

Vielen Dank für eure Hilfe

Lena
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich verstehe Dein Posting leider nicht wirklich. Was genau ist Dein Problem? Dass Du Zeilenumbrüche angeben musst? Falls ja: Das geht nun einmal nicht automatisch. Woher sollte denn Python wissen, wann Du eine neue Zeile willst und wann nicht! Was genau ist denn daran generell das Problem? Einen Zeilenumbruch anzugeben ist doch keine große Sache...

Wieso nennst Du denn eine Textdatei ``Test_2.py``? Die Endung "py" deutet an, dass es sich um Python-Quellcode handelt - dem ist ja offenbar nicht so...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@lena_92: Das klingt immer noch so als würdest Du Python-Quelltext-Dateien generieren wollen. Warum? Das sollte nicht nötig sein.
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

@Hyperion Danke für den Hinweis. Ich versuche das Problem besser zu beschreiben.

Die neue Textdatei soll wiederum ein Phyton-Quellcode sein, die dann später wieder benutzt werden soll. Die ganze "Übung" dient dazu, dass ein neuer Python-Quellcode entsteht. Dieser soll durch Variablen veränderlich sein. Das Grundgerüst steht schon und ist halt immer gleich.
Nun möchte ich dieses Grundgerüst in einer neuen Datei einfügen und die Variablen durch Werte ersetzten.

Leider ist das Grundgerüst Script sehr lange und ich möchte dies über datei.write() einfügen. Hierbei tritt nun die Frage auf.

Code: Alles auswählen

12.datei.write(
 
        "Diese Fuktion "  +config.get('section1', 'var1')+  " ist cool! Aber was kann man dazu noch sagen. \n"
             "Eine weitere Zeile. \n"
Wie kann ich "datei.write" sagen, dass dieser die neue Datei immer mit Zeilenumbrüche ausspucken soll. Im Moment fügt er mir das ganze Grundgerüst in einer Zeile zusammen.
Ich hatte an etwas wie
datei.write[n/]()
gedacht.

Ich hoffe, dass es nun verständlicher ist. Falls nicht - kurz Bescheid geben.
Lena
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@lena_92: Normalerweise möchte man keinen Source Code erzeugen, sondern Funktionen schreiben. Also statt:

Code: Alles auswählen

>>> my_template = """
... x = {}
... y = {}
... z = x + y
... """
>>>
>>> my_prog = my_template.format(2, 3)
>>> exec(my_prog)
>>>
>>> z
5
das hier:

Code: Alles auswählen

>>> def my_func(x, y):
...     return x + y
...
>>> z = my_func(2, 3)
>>> z
5
Welchen Grund gibt es denn, warum du unbedingt Source Code erzeugen musst?
In specifications, Murphy's Law supersedes Ohm's.
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

@pillmuncher

Ich möchte den erzeugten Quellcode dann in Abaqus öffnen und das Script in Abaqus laufen lassen.

Da ich neu dabei bin, kann es natürlich sein, dass ich einen völlig unnötigen und komplizierten Weg gehe. Wenn es eine Möglichkeit gibt, dass ich komplett anders an das Thema heran gehen, bin ich natürlich offen für alle Idee.
Grüße
Lena
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@lena_92: Mit Abaqus kenne ich mich nicht aus, aber ich vermute, dass du auch dort selbstgeschriebene Python-Module importieren kannst.
In specifications, Murphy's Law supersedes Ohm's.
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

@pillmuncher

Genau, ich kann dort Quellencode-Scripts importieren und laufen lassen. Ich möchte allerdings mit einem Script alle Möglichkeiten abdecken und dies mit den veränderlichen Variablen abdecken.
Daher brauche ich ein Quellcode Script zum Ende.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wenn Abaqus Python ausführen kann, wieso kannst Du dann nicht Dein bisheriges Grundgerüst (aka Template :-P ) nehmen und dieses - wie von pillmuncher angedeutet - generalisieren, so dass das Script selber die Konfigurationsdatei liest und entsprechend die Funktionen mit darin hinterlegten Werten ausführt. :K

Damit wird aus dem Template ein einziges, lauffähiges Python-Script, welches sich die Daten aus einer Konfigurationsdatei holt. Dein letzter Versuch macht ja eigentlich nichts anderes - außer, dass er als *zusätzliche unnötige Zwischenschicht* die Daten in ein Script einbaut, welches anschließend aufgerufen wird.

Der Ansatz zig verschiedene Python-Scripte zu erzeugen ist doch wesentlich umständlicher, als *direkt* die verschiedenen Daten abzuarbeiten.

Um es aber noch einmal klar zu sagen: Für das Ändern von einem Grundgerüst (aka Template), sollte man einen Templating-Mechanismus (bei mehr drum herum auch "Engine" genannt) nutzen. Dies schrieb ich oben ja bereits und pillmuncher zeigte das ebenfalls im Ansatz. Dies gilt natürlich nur für das allgemeine Problem, aus einem "fast allgemeinen Dokument mit Platzhaltern" spezifische Ausprägungen je nach Daten zu generieren. Für Dein Problem ist der Ansatz eben nicht sinnvoll.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Oder so:

Code: Alles auswählen

[foo]
x = 2
y = 3

[bar]
x = 4
y = 7
Das als lena.ini speichern.

Code: Alles auswählen

def my_func(x, y):
    return x + y
Das als lena.py speichern.

Und dann:

Code: Alles auswählen

>>> import configparser
>>> from lena import my_func
>>>
>>> config = configparser.RawConfigParser()
>>> config.read('lena.ini')
['lena.ini']
>>>
>>> x = int(config['foo']['x'])
>>> y = int(config['foo']['y'])
>>> print(x, y, my_func(x, y))
2 3 5
>>>
>>> x = int(config['bar']['x'])
>>> y = int(config['bar']['y'])
>>> print(x, y, my_func(x, y))
4 7 11
In specifications, Murphy's Law supersedes Ohm's.
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

Vielen Dank für die Hilfestellungen.
Ich werde mich daran versuchen.
Danke
Lena
Antworten