ich habe ein Problem beim import von openpyxl bzw. beim Ausführen des Codes.
In VS Code läuft alles, wie es soll. Egal, ob ich F5 drücke oder über den grünen Play-Button. Mein Code läuft durch und er macht es. Der ausgewählte Interpreter ist Python 3.9.2 64bit.
Wenn ich aber das Skript aus dem Ordner heraus (Doppelklick) starten möchte, dann scheitert er bei "import openpyxl". Woher ich das weiß?
from tkinter import messagebox
messagebox.showerror(title="Error Selektion", message="tkinter geht")
#import openpyxl
from openpyxl import load_workbook
messagebox.showerror(title="Error Selektion", message="openpyxl geht")
steht am anfang meines Codes. Das zweite Fenster von tkinter wird nicht mehr angezeigt, das Skript wird beendet. Wie gesagt, lustigerweise nicht, wenn ich es über VS Code starte. Ich habe sowohl import openpyxl und auch from openpyxl import ... versucht. Das Resultat war identisch.
Ich habe über "öffnen mit" zum Python 3.9 Ordner navigiert und da die korrekte Python 3.9 - python.exe und auch pythonw.exe ausgewählt und getestet. Leider ohne erfolg. Unter ..AppData\Local\Programs\Python\Python39\Lib\site-packages ist openpyxl installiert (3.0.6).
Wenn ich allerdings, das Skript per drag'n'drop auf die Python39\python(w).exe ziehe, dann läuft das Skript. Aber nicht über "öffnen mit 'damit'"? Ich versteh das nicht..
@tobi45f: Entweder hast Du noch ein anderes Python oder in VS-Code ein venv angelegt und nur in dem `openpyxl` installiert. Kannst Dir in VS-Code ja mal `sys.executable` anzeigen lassen, ob das der Interpreter ist, den Du erwartest.
“I am Dyslexic of Borg, Your Ass will be Laminated” — unknown
keine Ahnung, woran es jetzt wirklich lag, denn eigentlich sollte .py standardmäßig mit der richtigen Version geöffnet werden - aber scheinbar war das nicht der Fall. Ich habe die eine Version deinstalliert und jetzt geht es. Merkwürdig... und ja, openpyxl war nur in der einen Version installiert.
Gewöhne dir von Anfang an gleich an, sprechende Namen und Funktionen zu verwenden.
Es macht auch Sinn absolute Pfade zu verwenden und die dann als `Path`-Objekt anzugeben. Das kann man dann als Konstante deklarieren, dann muss man bei Änderungen, diese auch nur einmal im COde ändern.
Strings puzzelt man nicht mit + zusammen, sondern verwendet dafür `f` - Strings.
Das Programm funktioniert korrekt.
Wenn es eine "c:/Meine Python Programme/Bestellungen.xlsx" gibt und darin ein Tabellenblatt "Bestellungen" wird in E2 das Ergebnis von C2*D2 eingetragen.
Ich tippe darauf, dass du eine andere Datei anschaust und nicht die geänderte.
oder während des Programmlaufs ist die Datei noch in Excel geöffnet. Das führt im Zweifel auch zu Problemen, aber sollte meiner Meinung nach eher zum Programmabbruch durch eine Exception führen.
Das Problem ist, es wird die Datei automatisch in folgender Pfad angelegt:
C:\VTRoot\HarddiskVolume3\Meine Python Programme\
Habe das nur durch einen Zufall gefunden.
Warum das nicht, wie bei allen andern, gleich in den Ordner gespeichert wird, weis ich nicht.
Die Fehlermeldung sagt deutlich, dass man `os` importieren muss.
Jeder Prozess hat ein aktuelles Arbeitsverzeichnis, auf das sich relative Dateipfade beziehen. Wenn Du ein Programm startest, legst Du dieses Verzeichnis fest.
Ansonsten gilt, keine *-Importe, keine globalen Variablen und kein ausführbarer Code auf oberster Ebene.
Bei open_text fehlt ein e. Dateien öffnet nun mit with, damit sie auch verlässlich wieder geschlossen werden.
das hast du falsch verstanden. `open_text` benötigt ein Argument. Dass ist das was nach `def open_text` in der Klammer steht.
Im "Normalfall" wenn du die Funktion aufrufst, würdest du schreiben `open_text(my_text)` und dann wird die Funktion ausgeführt. Wenn du aber eine Funktion an einen Button zuweist, dann darfst du kein Klammerpaar hinter den Funktionsname schreiben, weil die Funktion dann gleich ausgeführt wird, wenn der Python-Interpreter die Zeile zum ersten mal "sieht" und nicht erst wenn der Button gedrückt wird. Mit `partial` kannst du nun eine Funktion mit Argument angeben, ohne dass die gleich ausgeführt wird.
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
vorab Danke für deine Unterstützung.
Ich hoffe es ist in Ordnung, wenn ich dir eine PM sende, da du mir schon ein paar mal weiter geholfen hast.
Das mit den *-Importen hab ich nicht gewusst, jetzt aber zur Kentniss genommen.
Warum wird in den Anfänger Tutorials, egal welche, ich habe jetzt schon ein paar durch, immer in der obersten Ebene ausführbare Codes und globale Variablen angewendet?
Durch die Videos, dachte ich globale Variablen setzt man immer am Anfang.
Der Code von dir besteht nur noch aus Funktionen(wenn ich es richtig gelernt habe heißt es so).
Ist das generell besser?
Diesen Befehl hab ich noch nie gesehen:
from functools import partial
Das ist mir jetzt am Anafang zu komplex.
Hab gerade gelsen was das macht und ich muss sagen, ich verstehe mit Glück die Hälfte^^.
CODE: ALLES AUSWÄHLEN
import tkinter as tk
from tkinter import filedialog
from functools import partial
def open_text(text_field):
text_file = filedialog.askopenfilename(initialdir="C:/Meine Python Programme/Text speichern/3 Code", title="Open Text File", filetypes=(("Text Files", "*.txt"), ))
with open(text_file, "r", encoding="utf8") as file:
stuff = file.read()
text_field.insert(tk.END, stuff)
def save_text(text_field):
with open("Gesamtliste.txt", "w", encoding="utf8") as file:
file.write(text_field.get(1.0, tk.END))
@Hans888: Videos bei Youtube kann jeder erstellen, da gibt's keine Qualitätskontrolle was die Inhalte betrifft. Viele Tutorials sind von Leuten die selber gerade mal mit Python angefangen haben. Teilweise ohne Vorerfahrung, teilweise mit Vorerfahrung in anderen Programmiersprachen, wo dann Gewohnheiten und Vorgehensweisen in Python übernommen werden die dort anders gehandhabt werden. Und dann gibt es halt auch einfach schlechte Programmierer, die zwar etwas funktionierendes basteln, das aber handwerklich nicht gut ist.
Es gibt auch noch den Unterschied zwischen „Ich zeige jetzt mal wie Konstrukt XY“ funktioniert, und „Ich schreibe ein echtes Programm“. Wenn man nur zeigen will wie ein bestimmtes Syntax-Konstrukt funktioniert und das in ein paar Zeilen Code geht, dann muss man da nicht unbedingt eine Funktion drum herum schreiben, wie man das in einem Programm machen würde.
Zuguterletzt gibt es Leute die zwischen ”Skripten” und ”Programmen” unterscheiden und es bei ersterem in Ordnung finden, das ohne Funktionen mit Code auf Modulebene zu schreiben. Bin ich kein Fan von, weil diese Unterscheidung sehr schwammig ist, und Code die Tendenz hat zu wachsen und irgendwann müsste man dann doch Funktionen einführen. Auf der anderen Seite macht es so gut wie gar keine Arbeit einfach immer mit einer `main()`-Funktion anzufangen und schon muss man sich gar keine Gedanken mehr darüber machen ob das nun ein ”Skript” oder ein ”Programm” ist, was man da gerade schreiben will.
Ich würde sagen kein Code auf Modulebene, der nicht dazu da ist Konstanten, Funktionen, und Klassen zu definieren, also ”nur Funktionen” ist generell besser. Man kann das Modul dann importieren, ohne dass das Programm abläuft. Zum Beispiel zur Fehlersuche interaktiv in einer Python-Shell, oder für automatisierte Tests aus einem anderen Modul heraus. Ausserdem gibt es noch nützliche Werkzeuge die erwarten, dass man ein Modul importieren kann, ohne das mehr passiert als die Definition von Konstanten, Funktionen, und Klassen. Beispielsweise welche die Dokumentation aus Docstrings erstellen. Mindestens ein Modul aus der Standardbibliothek (`multiprocessing`) erwartet das auch, damit es unter allen Betriebssystemen funktioniert.
Wenn Dir `functools.partial()` zu komplex ist, dann sind Dir „Closures“ zu komplex, und damit im Grunde auch Klassen. Mindestens eines davon, in der Praxis oft beides, braucht man für die GUI-Programmierung.
“I am Dyslexic of Borg, Your Ass will be Laminated” — unknown