Forum: PC-Programmierung Python 3: Merkwürdiger Effekt mit tkinter und re


von Bernd W. (berndwiebus) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo.

Ich habe das im Anhang befindlche Python 3 Programm pywwl_09Aug2012.py 
geschrieben.
Es bildet eine GUI für ein Komandozeilenprogramm in Linux, wwl, welches 
Entfernungen zwischen Planquadraten des Maidenhead-Locator Systems 
berechnet. Der Zweck des Programmes tut aber nichts zur Sache.

Problem:

Mit folgender Importdeklaration tritt erst einmal kein "Problem" auf:
1
09: import tkinter
2
10: from tkinter.filedialog import *
3
11: import sys
4
12: import subprocess 
5
13: from re import findall
Ändere ich aber Zeile 13 zu "from re import *",
erhalte ich die untenstehende Fehlermeldung von Idle 3.1.

Fehlermeldung:
Traceback (most recent call last):
  File "/home/wiebus/python/pywwl.py", line 105, in <module>
    Rahmen1.pack(side = TOP, fill = X)
  File "/usr/lib/python3.1/tkinter/__init__.py", line 1753, in 
pack_configure
    + self._options(cnf, kw))
_tkinter.TclError: bad fill style "64": must be none, x, y, or both

Die angemeckerte Zeile 105 steht in folgendem Bezug im Hauptfenster:
1
103: # Rahmen für beide Eingabe Entrys
2
104: Rahmen1 = Frame(Mainwindow, background = "#002040")
3
105: Rahmen1.pack(side = TOP, fill = X)
Es folgen weitere gleich aufgebaute Rahmendefinitionen, aber es wird 
natürlich nur die erste angemeckert.

Meine Frage: Eigentlich sollte der Stern in Zeile 13 ein Platzhalter für 
sämtliche dort befindliche Bibliotheken sein. Es funktioniert aber nur,
wenn ich aus dem Packet re speziell "findall" einbinde was eigentlich 
bedeutet, das sich idle mit dem Stern die falsche Bibliothek greift.
Allerdings kommt die Beschwerde aus tkinter, und nicht aus re (was mich 
absolut stutzig macht), wenn ich das richtig verstanden habe.
Letztlich wird in Zeile 105 kein regulärer Ausdruck untersucht, sondern 
ein frame definiert, in dem auch später nie nach regulären Ausdrücken 
gesucht wird. Oder sucht tkinter für sich selber dort nach regulären 
Ausdrücken?

Warum ist das so? Ist das ein Indiz, das irgendwo ein Name in den 
Bibliotheken doppelt vergeben wurde?

OS hier ist Debian squeeze mit Gnome.


Mit freundlichem Gruß: Bernd Wiebus alias dl1eic
http://www.dl0dg.de

von Yalu X. (yalu) (Moderator)


Lesenswert?

Bernd Wiebus schrieb:
> Ist das ein Indiz, das irgendwo ein Name in den Bibliotheken doppelt
> vergeben wurde?

Ja. Das tkinter-Modul definiert X='x', das re-Modul X=64. Laut
Fehlermeldung erwartet Tkinter entweder 'none', 'x', 'y' oder 'both',
stattdessen wird aber die Zahl 64 übergeben.

Beide Module enthalten Variablen und Funktionen mit recht allgemeinen
Namen. Solche Module sollten nicht mit

  from module import *

sondern mit

  import module

importiert werden, so dass der Modulname gleichzeitig als Namespace
dient. Dadurch entsteht zwar etwas mehr Schreibaufwand, weil du dann
tkinter.X bzw. re.X anstelle von X schreiben musst, dafür sind aber
Namensüberlappungen weitgehend ausgeschlossen.

Ist dir der tkinter-Prefix zu lang, kannst du das Modul auch so
importieren:

  import tkinter as tk

Dann geschieht der Zugriff auf X einfach mit tk.X. Du musst natürlich
dafür sorgen, dass keine andere Variable in deinem Programm tk heißt.

Du kannst auch auf die Benutzung der tkinter.X und ähnlicher Konstanten
ganz verzichten und stattdessen die entsprechenden Strings hinschreiben:

  Rahmen1.pack(side = 'top', fill = 'x')

Das löst das Problem ebenfalls.

von Bernd W. (berndwiebus) Benutzerseite


Lesenswert?

Hallo Yalu X.

Danke für Deine Antwort.

> Ja. Das tkinter-Modul definiert X='x', das re-Modul X=64. Laut
> Fehlermeldung erwartet Tkinter entweder 'none', 'x', 'y' oder 'both',
> stattdessen wird aber die Zahl 64 übergeben.

Ich habs befürchtet. Mir war auch irgendwie schleierhaft, wie man das 
bei den knapp bemessenen Variablennanen hinkriegen wollte.


> Beide Module enthalten Variablen und Funktionen mit recht allgemeinen
> Namen. Solche Module sollten nicht mit
>
>   from module import *
>
> sondern mit
>
>   import module
>
> importiert werden, so dass der Modulname gleichzeitig als Namespace
> dient. Dadurch entsteht zwar etwas mehr Schreibaufwand, weil du dann
> tkinter.X bzw. re.X anstelle von X schreiben musst, dafür sind aber
> Namensüberlappungen weitgehend ausgeschlossen.

Vermutlich die sauberste Lösung. Mit dem Ausschreiben hat jemand, der 
manuell Datestamps in Dateinahmen schreibt, vermutlich kein Problem. ;O)

>
> Ist dir der tkinter-Prefix zu lang, kannst du das Modul auch so
> importieren:
>
>   import tkinter as tk
>
> Dann geschieht der Zugriff auf X einfach mit tk.X. Du musst natürlich
> dafür sorgen, dass keine andere Variable in deinem Programm tk heißt.


Na, wenn ich dort wieder zusätzliche Namen einführe, mache ich das ganze 
ja noch undurchsichtiger und verschärfe letztlich das Problem. ;O)

Trozdem gut, dass Du das erwähnst, weil ich jetzt auch weiss, warum 
manche Leute tkinter unbedingt als tk importieren wollen. ;O)



> Du kannst auch auf die Benutzung der tkinter.X und ähnlicher Konstanten
> ganz verzichten und stattdessen die entsprechenden Strings hinschreiben:
>
>   Rahmen1.pack(side = 'top', fill = 'x')
>
> Das löst das Problem ebenfalls.

Mmmmh. In dem Punkte hatte ich schon angefangen, meine Lehrbücher zu 
durchfleddern. Darüber schweigen sie. Allerdings findet sich das eben 
oft in Beispielen, und ich habe mich auch gefragt, warum mal so und mal 
so.

Nochmals danke für Deine Ausführungen, das hilft mir jetzt gut weiter.

Mit freundlichem Gruß: Bernd Wiebus alias dl1eic
http://www.dl0dg.de

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.