Variableninhalt als Dateinamen verwenden?

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
duodiscus
User
Beiträge: 97
Registriert: Sonntag 6. April 2014, 16:10

Hallo zusammen,
ich habe zum Test ein Programm geschrieben, welches einen Namen vom Anwender per input Befehl verlangt. Dieser Name wird in einer Variablen hinterlegt (in diesem Fall name_person).
Jetzt möchte ich eine .txt datei erstellen, die den Dateinamen der vorherigen Eingabe aus der Variable trägt.

Code: Alles auswählen


name_person = eval(input('Name für Person eintragen: ')
f=open('/Users/Documents/name_person' , 'wb')

So wie dargestellt scheint das nicht zu funktionieren. Weiß jemand wie ich das einfach auf die Reihe bekomme? Danke schonmal! 8)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo,

das eval is falsch und solltest du gleich weglassen. Was glaubst du, was es tut? Dateien solltest du immer mittels with-Statement öffnen, dann werden sie auch wieder geschlossen. Gerade bei zu schreibenden Dateien ist das von Vorteil ;-) Dateipfade kannst du mittels os.path.join zusammensetzen:

Code: Alles auswählen

pfad = os.path.join("/Users/Documents", name)
Das Leben ist wie ein Tennisball.
BlackJack

@duodiscus: Vergiss am besten erst mal das es `eval()` gibt. Du willst da nur `input()` verwenden (`raw_input()` in Python 2).

Und dann musst Du den Pfad aus dem festen Teil und dem Inhalt der Variablen zusammen setzen. Das geht natürlich nicht in dem Du in die Zeichenkette einfach den Variablennamen rein schreibst. Python kann ja nicht raten was davon so wie's geschrieben ist gemeint ist und was durch Variableninhalte ersetzt werden soll.

Zeichenkettenformatierung funktioniert mit dem ``%``-Operator oder der `format()`-Methode auf Zeichenketten. Und Pfadteile sollte man mit der `os.path.join()`-Funktion zusammen setzen, denn '/' ist ja nicht überall der Pfadtrenner.
duodiscus
User
Beiträge: 97
Registriert: Sonntag 6. April 2014, 16:10

@EyDuDanke für deine Antwort erstmal. Ich habe es so gezeigt bekommen, mit open( ... ) zu nutzen. Vielleicht liegt es daran, das dieses System sich besser für Anfänger eignet? Ich weiß es nicht.
Eval setze ich ein, damit er prüft was es für eine Eingabe ist und dieser direkt einen Typ mitgibt. In diesem Fall damit ein String übergeben wird. Okay, vllt. hier unnötig.

Code: Alles auswählen


pfad = os.path.join("/Users/Documents", name)  # name steht hier also für die variable wie in meinem Fall name_person?

Ich möchte die Datei ja erstellen mit dem Namen (name_person) und danach möchte ich ja noch diverse Dinge darein schreiben. Daher soll sie ruhig geöffnet bleiben! Schließen würde ich sie nach der Aufgabe. Bisher immer gemacht mit f.close()
Benutzeravatar
ngulam
User
Beiträge: 35
Registriert: Freitag 18. Oktober 2013, 11:03

da war doch noch was....

Variablennamen in Englisch - sie sollen den Inhalt beschreiben

Code: Alles auswählen

pathfilename_person = os.path.join("/path/to/data", name_person)
... und die Eingabe sollte vllt. noch auf gültigen Inhalt geprüft werden ( bspw. [max.!] Länge prüfen, keinen "/" oder "\" enthalten)
งูหลาม
duodiscus
User
Beiträge: 97
Registriert: Sonntag 6. April 2014, 16:10

Danke BlackJack, habe es erstmal so wie bei uns vorgegeben gemacht, und es mit der Formatierung und dem % Operator gemacht. Wusste net, das der da auch so funktioniert!
BlackJack

@duodiscus: `eval()` ist nicht zur überpüfung oder um „einen Typ mitzugeben”, sondern das zwingt den Benutzer dazu gültiges Python einzugeben was dann *ausgewertet* wird. Der Benutzer kann da alles mögliche eingeben, inklusive Quelltext der Dateien löscht, oder etwas am laufenden Programm ändert, was nicht für den Benutzer zu verändern vorgesehen ist. Das ist eine Sicherheitslücke und auch bei netten Benutzern schlecht robust benutzbar, weil diese Zeile, je nachdem was der Benutzer eingibt, zu so ziemlich jeder nur erdenklichen Ausnahme führen kann. `input()` gibt grundsätzlich nur die Eingabe als Zeichenkette zurück, ohne damit irgend etwas anzustellen. Ich würde `eval()` an der Stelle nicht nur als unnötig, sondern als Programmfehler ansehen.

Du kannst vor dem Schliessen ja ruhig etwas mit der Datei machen, der ``with``-Block sorgt aber dafür das sie am Ende des Blocks *auf jeden Fall* geschlossen wird, egal warum der Block verlassen wird. Das ist bei einem manuellen Aufruf von `close()` nicht garantiert. Ausser man sichert das mit einem ``try``/``finally`` ab.

@ngulam: English wäre dann aber eher `person_name` oder `persons_name`. Und prüfen auf gültigen Inhalt ist schwierig, denn was ist denn *die* maximale Länge? Und warum sollte man unter Betriebssystemen wo der Pfadtrenner der Doppelpunkt ist keine \ oder / im Namen haben? Das sollte man plattformunabhängig prüfen, beziehungsweise einfach versuchen die Datei zu öffnen. Das wird dann gegebenenfalls schon fehlschlagen.
Benutzeravatar
ngulam
User
Beiträge: 35
Registriert: Freitag 18. Oktober 2013, 11:03

BlackJack hat geschrieben:gültigen Inhalt ist schwierig, denn was ist denn *die* maximale Länge?
Optimal wären plattform-unabhängige Prüfungen - da gebe ich Deiner Aussage auch Recht, dass dies schwierig wird.

Für *meine* Plattform weiss ich jedoch sowohl Dateinamen-Länge und (Zitat: "bspw" !) auch die Ungültigkeit von "\", "/" ... oder auch "\n", "\t", und "\r"
Da prüfe ich dann lieber und gebe ich ggfs. eine aussagekräftige Fehlermeldung aus.

Und zum "English": bleibe bei meiner Variante, denn der Inhalt der Variablen ist nicht "persons" oder "persons_name", sondern Pfad- und Dateiname zur zu erstellenden Datei :)
งูหลาม
BlackJack

@ngulam: Sicher dass das alles Einschränkungen der Plattform sind? Was verwendest Du? DOS? ;-)

Zum Namen: Ich meinte `name_person`. Aber `pathfilename_person` hat das gleiche Problem mit der Reihenfolge.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

EyDu hat geschrieben:Dateipfade kannst du mittels os.path.join zusammensetzen:

Code: Alles auswählen

pfad = os.path.join("/Users/Documents", name)
Wäre es nicht so besser?

Code: Alles auswählen

pfad = os.path.join(os.path.sep, 'Users', 'Documents', name)
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

mutetella hat geschrieben:Wäre es nicht so besser?

Code: Alles auswählen

pfad = os.path.join(os.path.sep, 'Users', 'Documents', name)
Naja, das hat hier das selbe Ergebnis wie das eigentlich für solche Anwendungsfälle vorgesehene `os.path.join`. Welchen Vorteil siehst du darin, das so zu machen?

BTW: Kommt Windows nicht (inzwischen?) auch mit Pfadtrennern aus der Unix-Welt klar?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

mutetella hat geschrieben:Wäre es nicht so besser?

Code: Alles auswählen

pfad = os.path.join(os.path.sep, 'Users', 'Documents', name)
In diesem Fall ist das wohl relativ egal. Dein eingeführtes ``os.path.sep`` schafft hier übrigens mehr Probleme als Lösungen, da dies nicht unbedingt das root-Verzeichnis sein muss. Unter Unix fällt das eben "zufällig" mit dem Pfadtrenner überein, unter Windows ist die Angabe falsch. Wenn man es ganz systemunabhängig haben will, dann muss man eben noch mehr drum herum basteln. Da hatte ich einfach keine Lust drauf.
Das Leben ist wie ein Tennisball.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

snafu hat geschrieben:Welchen Vorteil siehst du darin, das so zu machen?
Ich dachte halt, dass u. a. das plattformunabhängige Setzen der Pfadtrenner mit der Grund ist, `os.path.join()` zu verwenden und die Übergabe von "hart gesetzten" Pfadtrennern dies wieder ad absurdum macht.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Antworten