Forum: PC-Programmierung Variable nicht definiert


von Kev G. (kev_g)


Lesenswert?

Hey ich bin nicht erfahren im Programmieren deswegen hoff ich auf eure 
Hilfe:
Ich habe ein Programm erstellt welches ein anderes aufrufen soll aber es 
sei anscheinend die Variable nicht definiert

Hier das Hauptprogramm:

from tkinter import *


fenster = Tk()

fenster.geometry("700x350")
fenster.title("Sortiment verwalten")

rahmen = Frame(fenster, relief = "ridge", borderwidth = 10)
rahmen.pack(fill="both", expand = 1)

###_Zeile 18 Fehler_####
button = Anzeigen (rahmen,text="Sortiment anzeigen", width = 20, height 
= 5)
button.config(font=("Arial", 12, "bold"))
button["command"] = button.Anzeigen
button.place(x = 50, y = 50)

.
.
.


Hier das andere Programm:

class Anzeigen (Button):
    def anzeigen (self):
        fenster = Tk()
        fenster.geometry("500x400")

.
.
.


Der Fehler besagt das:

line 18, in <module>
    button = Anzeigen (rahmen,text="Sortiment anzeigen", width = 20, 
height = 5)
NameError: name 'Anzeigen' is not defined

von Heiner (Gast)


Lesenswert?

Kev G. schrieb:
> from tkinter import *

Von dieser Art des Imports (wildcard) in Python wird allgemein abgeraten 
(namespace pollution, google). Besser ist
1
from tkinter import Tk, Frame

(wahrscheinlich noch mehr, aber das passt zum gezeigten Ausschnitt) oder
1
import tkinter

und dann z.B.
1
fenster = tkinter.Tk()

Damit sind wir auch schon bei deiner Frage:

Kev G. schrieb:
> Ich habe ein Programm erstellt welches ein anderes aufrufen soll aber es
> sei anscheinend die Variable nicht definiert

Ob das zweite ein Programm ist, lassen wir mal dahingestellt, aber es 
ist eine eigene Datei. Die muss in die erste Datei importiert werden. 
Falls sie sich im gleichen Verzeichnis befindet und anzeigen.py heißt, 
ginge das z.B. mit
1
import anzeigen

oder
1
from anzeigen import Anzeigen

Wie man im ersten Fall den Aufruf verändern musst, findest du auf Basis 
der Informationen oben selbst raus.

von Kev G. (kev_g)


Lesenswert?

Habe es jetzt umgeschrieben

import tkinter



fenster = tkinter.Tk()


fenster.geometry("700x350")
fenster.title("Sortiment verwalten")


rahmen = Frame(fenster, relief = "ridge", borderwidth = 10)
rahmen.pack(fill="both", expand = 1)


button = Anzeigen (rahmen,text="Sortiment anzeigen", width = 20, height 
= 5)
button.config(font=("Arial", 12, "bold"))
button["command"] = button.Anzeigen
button.place(x = 50, y = 50)
.
.
.
.
from anzeigen import Anzeigen

fenster.mainloop()

Dennoch kommt jetzt der Fehler:

line 14, in <module>
    rahmen = Frame(fenster, relief = "ridge", borderwidth = 10)
NameError: name 'Frame' is not defined



Danke für jede Hilfe !

von Heiner (Gast)


Lesenswert?

Kev G. schrieb:
> import tkinter

Kev G. schrieb:
> fenster = tkinter.Tk()

Kev G. schrieb:
> rahmen = Frame(fenster, relief = "ridge", borderwidth = 10)

Einmal ruhig durchatmen und erkennen, warum das eine funktioniert und 
das andere nicht.

Bevor du kompliziertere Geschichten mit tkinter machst, versuche zuerst 
die Sprache und ihre Konstrukte zu verstehen. Man muss nicht alle 
Kuriositäten von Python verstanden haben, bevor man es sinnvoll 
einsetzen kann, aber wenn es bei import und Namensräumen schon 
scheitert, ...

von Egon D. (Gast)


Lesenswert?

Heiner schrieb:

> Kev G. schrieb:
>> rahmen = Frame(fenster, relief = "ridge", borderwidth = 10)
>
> Einmal ruhig durchatmen und erkennen, warum das eine
> funktioniert und das andere nicht.

Jeopardy: "Was ist Case-Sensitivität?"


> Bevor du kompliziertere Geschichten mit tkinter machst,
> versuche zuerst die Sprache und ihre Konstrukte zu
> verstehen. Man muss nicht alle Kuriositäten von Python
> verstanden haben, bevor man es sinnvoll einsetzen kann,

Naja.
Jedesmal, wenn ich irgendwas von Tkinter sehe, bin ich
heilfroh, dass es Tcl/Tk gibt...

Aber das ist nur meine ganz persönliche Sicht.

von Heiner (Gast)


Lesenswert?

Egon D. schrieb:
> Jeopardy: "Was ist Case-Sensitivität?"

Nein. Zur "Belohnung" PEP 8 lesen. Die Großschreibung ist Absicht und 
korrekt.

Egon D. schrieb:
> Jedesmal, wenn ich irgendwas von Tkinter sehe, bin ich
> heilfroh, dass es Tcl/Tk gibt...

Das hier geschilderte Problem würde es auch mit Tcl (und vermutlich mit 
allem, was objektorientiert in einem Modul daherkommt) bestehen. Es 
ist einfach ein grundsätzlicher Mangel an Verständnis dafür, wie import 
den Namensraum beeinflusst.

Deshalb auch die leicht kryptische Antwort. Es nützt nichts, den 
(kleinen!) Fehler zu korrigieren, weil Kev dann ein paar Zeilen weiter 
beim nächsten Fehler  gleicher Art wieder fragen muss.

von Egon D. (Gast)


Lesenswert?

Heiner schrieb:

> Egon D. schrieb:
>> Jeopardy: "Was ist Case-Sensitivität?"
>
> Nein.

Dann halt nicht.
War nur geraten; betrifft mich ja nicht.


> Zur "Belohnung" PEP 8 lesen.

Habe ich das richtig verstanden: Du kennst die
korrekte Antwort und empfiehlst dennoch einem
Tcl-Anwender, gefälligst den Python-Styleguide zu
lesen?

Welches mentale Problem hast Du eigentlich?


> Egon D. schrieb:
>> Jedesmal, wenn ich irgendwas von Tkinter sehe, bin
>> ich heilfroh, dass es Tcl/Tk gibt...
>
> Das hier geschilderte Problem würde es auch mit Tcl
> (und vermutlich mit allem, was objektorientiert in
> einem Modul daherkommt) bestehen.

Komisch, dass ich ihm nie begegnet bin. Ich schreibe
einfach...
1
wm title . "Sortiment anzeigen" 
2
wm geometry . "700x350" 
3
4
frame .rahmen -relief ridge -borderwidth 10 
5
pack .rahmen -fill both -expand yes
...ohne irgendwelches Gehampel davor und bin glücklich.
(Natürlich, den "wish" sollte man schon aufrufen.)


> Es ist einfach ein grundsätzlicher Mangel an Verständnis
> dafür, wie import den Namensraum beeinflusst.

Um Tk aus Tcl heraus verwenden zu können, muss ich nix
importieren, und mit Namensräumen hat das (unter Tcl)
auch nix zu tun.

von Kev G. (kev_g)


Lesenswert?

Versuche lediglich es zu lernen und Übung macht den Meister aber man 
kann natürlich auch mal Hänger haben bei grundlegenden Sachen wenn man 
sich alles selber beibringen muss.
Ich hab alles aus dem Internet gelernt aber solche Antworten helfen mir 
dann auch nicht weiter ...

Trotzdem danke oder so

von Heiner (Gast)


Lesenswert?

Egon D. schrieb:
> Welches mentale Problem hast Du eigentlich?

Dich. Sonst ist die Welt ganz gut in Ordnung.

Kev G. schrieb:
> Ich hab alles aus dem Internet gelernt aber solche Antworten helfen mir
> dann auch nicht weiter ...

Eine Suche nach python, import und Namensraum (genau meine Hinweise) 
liefert z.B. das hier:

https://www.data-science-architect.de/importtechniken-in-python/

Die Arbeit musst du schon selbst machen. Das tut am Anfang weh, der 
Schritt von "fremden Code lesen und verwenden" zu "eigenen Code 
schreiben" ist riesig. Mit der Zeit wird es besser, aber es gibt keinen 
Ersatz dafür, sich selbständig dieses Zeug anzulesen und anzuwenden. 
Wenn ich dir einfach die Lösung sage (tkinter.Frame(...)), stehst du 4 
Zeilen später wieder genau so ahnungslos dar.

von Egon D. (Gast)


Lesenswert?

Heiner schrieb:

> Egon D. schrieb:
>> Welches mentale Problem hast Du eigentlich?
>
> Dich.

Das glaube ich nicht, Tim.


> Wenn ich dir einfach die Lösung sage (tkinter.Frame(...)),

Es war zwar ein SEHR steiniger Weg bis dahin, aber dennoch:
Danke.

von Sheeva P. (sheevaplug)


Lesenswert?

Kev G. schrieb:
1
> from tkinter import *
2
> 
3
> fenster = Tk()

Hallo, bitte entschuldige, aber anscheinend hast Du meinen Hinweis in 
Deinem letzten Thread (noch?) nicht gelesen. Bitte schau' mal hier: [1].

[1] 
Beitrag "Re: Frame wird nicht erkannt (Python3.0)"

> Der Fehler besagt das:
>
> line 18, in <module>
>     button = Anzeigen (rahmen,text="Sortiment anzeigen", width = 20,
> height = 5)
> NameError: name 'Anzeigen' is not defined

Leider sehe ich allerdings in Deinem Code nirgends, daß eine Variable 
"Anzeigen" zugewiesen, oder daß sie importiert wird. Du hast eine Klasse 
"Anzeigen", die keinen Konstruktor hat, zumindest zeigst Du dessen Code 
nicht. Aber daß Du den Code nicht zeigst, ist völlig okay -- was (für 
Python) dagegen nicht okay ist, ist, daß Du das Modul mit der Klasse 
"Anzeigen" nicht importierst.

Übrigens wird die Sache für uns alle leichter, wenn Du Deinen Code 
entweder mit den entsprechenden Tags auszeichnest, oder in einfach an 
Deine Beiträge anhängst oder ihn zumindest mit den entsprechenden 
Markierungen versiehst. Dazu findest Du über den Eingabefeldern extra 
einen Abschnitt "Formatierung", bitte lies ihn -- wenn Du Fragen dazu 
hast, scheue Dich bitte nicht, sie zu stellen. Merci! :-)

von Sheeva P. (sheevaplug)


Lesenswert?

Kev G. schrieb:
> line 14, in <module>
>     rahmen = Frame(fenster, relief = "ridge", borderwidth = 10)
> NameError: name 'Frame' is not defined
1
tkinter.Frame(...)

von Sheeva P. (sheevaplug)


Lesenswert?

Egon D. schrieb:
> Jeopardy: "Was ist Case-Sensitivität?"

Gegenfrage: wo siehst Du diesbezüglich ein Problem? ;-)

von Sheeva P. (sheevaplug)


Lesenswert?

Egon D. schrieb:
> Heiner schrieb:
>> Egon D. schrieb:
>>> Jeopardy: "Was ist Case-Sensitivität?"
>> Zur "Belohnung" PEP 8 lesen.
>
> Habe ich das richtig verstanden: Du kennst die
> korrekte Antwort und empfiehlst dennoch einem
> Tcl-Anwender, gefälligst den Python-Styleguide zu
> lesen?

Heiner empfiehlt es nicht ihm. Er empfiehlt es Dir, lieber Egon. ;-)

> Komisch, dass ich ihm nie begegnet bin. Ich schreibe
> einfach...

Wie schön, daß ich mir das hier [1] nur einbilde und / oder man in TCL 
dabei keine Fehler machen kann...

[1] https://www.tcl.tk/man/tcl8.5/tutorial/Tcl31.html

>
1
> wm title . "Sortiment anzeigen"
2
> wm geometry . "700x350"
3
> 
4
> frame .rahmen -relief ridge -borderwidth 10
5
> pack .rahmen -fill both -expand yes
6
>
> ...ohne irgendwelches Gehampel davor und bin glücklich.
> (Natürlich, den "wish" sollte man schon aufrufen.)

Wer ist eigentlich dieses Fräulein Shebang? :-)

>> Es ist einfach ein grundsätzlicher Mangel an Verständnis
>> dafür, wie import den Namensraum beeinflusst.
>
> Um Tk aus Tcl heraus verwenden zu können, muss ich nix
> importieren, und mit Namensräumen hat das (unter Tcl)
> auch nix zu tun.

Tja, Python ist -- erfreulicherweise -- eine in syntaktischer Hinsicht 
besonders minimalistische Sprache, da muß man sogar Module wie "os" und 
"sys" importieren, wenn man etwas daraus benutzen will. Der BDFL Guido 
van Rossum ist auch extrem vorsichtig, was die Verschmutzung des 
globalen Namensraumes angeht, deswegen hat Python besonders wenige 
Schlüsselworte -- aber dafür ist das Importieren in der Sprache 
besonders flexibel und erlaubt es, wie in meinem oben verlinkten 
Beispiel gezeigt und sehr gebräuchlich, Module und Pakages unter einem 
anderen Namen oder lediglich bestimmte Symbole daraus zu importieren, 
auch diese auf Wunsch unter einem anderen Namen.

von Egon D. (Gast)


Lesenswert?

Sheeva P. schrieb:

> Egon D. schrieb:
>> Jeopardy: "Was ist Case-Sensitivität?"
>
> Gegenfrage: wo siehst Du diesbezüglich ein Problem? ;-)

Da ich zwar Tk, aber weder python noch tkinter kenne, hatte
ich vermutet , dass der aufgetretene Fehler mit "frame"
und "Frame" zu tun hat. Ist aber offenbar nicht so.

Die nächste Falle ist, dass die Notation "foo.Bar" nix
mit der Widget-Hierarchie zu tun hat, wie sie Tcl/Tk
verwendet, sondern offenbar eine reine Python-Namespace-
Geschichte ist (die unter Tcl "foo::bar" heißen würde).

Scheint also ein reines Python-Problem zu sein, das
überhaupt nicht spezifisch für tkinter ist. War mir
anfangs nicht klar.

von Sheeva P. (sheevaplug)


Lesenswert?

Kev G. schrieb:
> Versuche lediglich es zu lernen und Übung macht den Meister aber man
> kann natürlich auch mal Hänger haben bei grundlegenden Sachen wenn man
> sich alles selber beibringen muss.
> Ich hab alles aus dem Internet gelernt aber solche Antworten helfen mir
> dann auch nicht weiter ...

Probier's doch einfach mal mit dem offiziellen Tutorial, hier findest Du 
[1] die deutschsprachige Version. Wenn Du magst, arbeite sie einfach mal 
durch, und wenn Du Fragen hast, bekommst Du gleich meine Mailadresse per 
PN.

Ansonsten herzlich willkommen in der Welt der Programmierer, in der 
jeder seine Sprache, seinen Editor, seine Datenbank, und 
was-weiß-ich-was-sonst-noch-alles unbedingt immer für das Nonplusultra 
hält. Aber mach' Dir nichts 'draus und laß' Dich nicht beirren: Du hast 
eine gute Wahl getroffen. Es gibt gute Gründe, warum Python seit Jahren 
einen der Spitzenplätze in allen renommierten Umfragen belegt, während 
Egons Tcl es nicht einmal unter die ersten 20 schafft... :-)

[1] https://py-tutorial-de.readthedocs.io/de/python-3.3/

von Kev G. (kev_g)


Lesenswert?

Danke, je werde ich machen nachdem ich mit dem Buch von Michael Bonacina 
durch bin^^
Vielen Dank :)!!!

von Sheeva P. (sheevaplug)


Lesenswert?

Egon D. schrieb:
> Da ich zwar Tk, aber weder python noch tkinter kenne, hatte
> ich vermutet , dass der aufgetretene Fehler mit "frame"
> und "Frame" zu tun hat. Ist aber offenbar nicht so.

Nein, isses nicht. ;-)

> Die nächste Falle ist, dass die Notation "foo.Bar" nix
> mit der Widget-Hierarchie zu tun hat, wie sie Tcl/Tk
> verwendet, sondern offenbar eine reine Python-Namespace-
> Geschichte ist (die unter Tcl "foo::bar" heißen würde).
>
> Scheint also ein reines Python-Problem zu sein, das
> überhaupt nicht spezifisch für tkinter ist. War mir
> anfangs nicht klar.

Jaaaa.... nein. Es ist kein Problem von Python, ganz im Gegenteil: es 
ist (auch) in dieser Hinsicht im Gegensatz zu fast allen anderen 
Sprachen absolut konsistent und nutzt für den Separator immer den Punkt 
'.', ganz gleichgültig, ob eine Funktion in einem Modul, Paket, 
Unterpaket, oder eine Methode aufgerufen werden soll. In Python es kein 
Mischmasch wie '.' und '->' wie unter C, was C++ noch um den '::' 
erweitert und PHP sogar noch um das -- wie ich finde -- potthäßliche und 
unlesbare '\\'.

von Sheeva P. (sheevaplug)


Lesenswert?

Kev G. schrieb:
> Danke, je werde ich machen nachdem ich mit dem Buch von Michael Bonacina
> durch bin^^
> Vielen Dank :)!!!

Da nicht für... frins Warte, bis ich die harte Literatur empfehle. :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.