Seite 1 von 1

werte aus dict lesen

Verfasst: Mittwoch 30. August 2006, 21:00
von pyStyler
Hallo,

wie würdet ihr das folgende Problem lösen.

Code: Alles auswählen

from Tkinter import *

class Demo:
	def __init__(self, fenster):
		self.root=fenster
		
		self.wdict= {'aname':10,
					'cname':30,
					'bname':20,
					'dname':40,
				}
					
		for xv in range(len(self.wdict)):
			setattr(self, 'of%s' %xv, Frame(self.root) )
			
		for name in self.wdict.keys():
			button=Button(getattr(self, 'of%s' %xv),
				text=name,width=14, height=4,
				command=lambda s=self,
					wert=name :s.ausgabe(wert ))
						
			button.pack(side=LEFT, padx=2, pady=2, expand=YES, fill=BOTH)
			getattr(self, 'of%s' %xv).pack(expand=YES, fill=BOTH)
			
	def ausgabe(self, x):
		a=self.wdict.get(x)
		print a
if __name__=='__main__':
	root=Tk()
	Demo(root)
	root.mainloop()
es muss doch irgendwie auch einfacher gehen ? :roll:

schonmal danke.

Gruss
pyStyler

Verfasst: Mittwoch 30. August 2006, 22:00
von Michael Schneider
Hi PyStyler,

wow, ich bin mir nicht sicher, ob ich mit meiner jetzigen Erfahrung einen solch anspruchsvollen Code zusammenbekommen hätte (so dass er auch noch funktioniert)! Wie kommst Du auf diese (sorry) "Hintertürfunktionen" getattr und setattr? Die kann man gebrauchen, wenn man Namen deklarieren will, die als Strings vorliegen und später direkt als Name aufgerufen werden sollen, etwa so:

Code: Alles auswählen

>>> class dummy:pass
>>> test = dummy()
>>> setattr(test,"a", "Hallo welt")
>>> test.a
'Hallo welt'
Meistens kann man das aber schöner über Dictionaries oder sogar Listen lösen. In diesem Fall brauchst nichts außer dem eingangs definierten Dictionary.

Diese Klasse macht zumindest äußerlich das gleiche:

Code: Alles auswählen

class Demo:
    def __init__(self, fenster):
        self.root=fenster
       
        self.wdict= {'aname': 10,
                     'cname': 30,
                     'bname': 20,
                     'dname': 40
                    }

        ##  Wofuer brauchst Du die Frames??
        #for xv in range(len(self.wdict)):
        #    setattr(self, 'of%s' %xv, Frame(self.root) )
           
        for name, wert in self.wdict.items():

            ##  Funktion die die Ausgabefunktion aufruft
            ##  der Wert koennte eventuell auch gleich hier ausgegben werden
            def command_function(wert = wert):
                self.ausgabe(wert)
                #print wert          ## Alternative

            Button(fenster, text=name, width=14, height=4,command=command_function)\
                  .pack(side=LEFT, padx=2, pady=2, expand=YES, fill=BOTH)
                                  
    def ausgabe(self, x):
        """Gibt den Parameterwert x aus"""
        print x
Sie legt aber keine Frames an, in denen nur ein Button liegt. Wenn das Anforderung ist, okay. Aber ich sehe darin im Normalfall keinen Sinn.
Und wenn die Ausgabe-Methode nur den Wert des Buttons ausgeben soll, kannst Du sie Dir auch sparen und den Wert gleich in der Funktion <command_function> ausgeben lassen.

Kurzfassung:

Code: Alles auswählen

class Demo:
    def __init__(self, fenster):
        self.root=fenster
        self.wdict= {'aname': 10, 'cname': 30, 'bname': 20, 'dname': 40}

        for name, wert in self.wdict.items():
            def command_function(wert = wert): print wert
            Button(fenster, text=name, width=14, height=4,command=command_function)\
                  .pack(side=LEFT, padx=2, pady=2, expand=YES, fill=BOTH)
Grüße,
Michael

Verfasst: Donnerstag 31. August 2006, 10:13
von pyStyler
Hallo Michael,
ersteinmal danke für deine so ausführliche Antwort , es hat mir sehr geholfen.
Michael Schneider hat geschrieben: wow, ich bin mir nicht sicher, ob ich mit meiner jetzigen Erfahrung einen solch anspruchsvollen Code zusammenbekommen hätte (so dass er auch noch funktioniert)! Wie kommst Du auf diese (sorry)
in einem Buch von mir, wird so ein ähnlicher Codestück gezeigt.

Auch neige ich sehr oft dazu, für einfache Dinge sehr Kompliziert zu denken. ( ( ist das normal ? ) nur was natürlich python angeht )

Danke&Gruss
pyStyler


p.s vlt hat noch jemand ne andere Idee nur interessenhalber

Verfasst: Donnerstag 31. August 2006, 17:34
von Michael Schneider
Hi PyStyler,

wie wäre es, wenn Du einfach mal mit der Aufgabe anfängst? :) Das hilft ungemein, wenn man Code optimieren möchte. :D Man kann sie auch grob aus dem Inhalt entnehmen, aber beispielsweise ob die Frames da drin gefordert waren, kann man so nicht wissen.

Es ist wirklich schwierig, trivial genug für Python zu denken. Formuliere einfach, was das Programm machen soll, und schreib es auf. Dann noch einrücken und Dein Programm ist fertig. ;-)

Okay, ganz so einfach ist das auch wieder nicht, aber Du kannst in Python wirklich viele Dinge so programmieren, wie Du normal denkst, nicht wie Du in C denken würdest.

Michael

Verfasst: Donnerstag 31. August 2006, 19:58
von pyStyler
Hi,

Frame wird ( wurde ) doch gebraucht um die Buttons daran anzubinden oder sehe ich das falsch ?
Python GE-Packt hat geschrieben:

Code: Alles auswählen

setattr(object, name, value)
"""
Die Argumente sind ein Objektbezeichner, ein String mit dem Namen
eines Atributes des Objektes und ein Wert.
"""
Gruss
pyStyler

Verfasst: Donnerstag 31. August 2006, 21:38
von BlackJack
pyStyler hat geschrieben:Frame wird doch gebraucht um die Buttons anzubinden oder sehe ich das falsch ?
Woran anbinden? Michaels Code funktioniert doch auch ohne Frames, oder nicht!?

Einen Frame verwendet man üblicherweise um dort mehrere Widgets zu platzieren und diese dann als ein ganzes Objekt in die GUI einzufügen.

Verfasst: Donnerstag 31. August 2006, 22:00
von pyStyler
BlackJack hat geschrieben: Woran anbinden? Michaels Code funktioniert doch auch ohne Frames, oder nicht!?
ja stimmt der Code funktioniert Wunderbar aber das hier unten von Michael
Michael hat geschrieben: die Frames da drin gefordert waren, kann man so nicht wissen
habe ich es eher auf den ersten Post von mir bezogen.

hier das gemeinte Codestück

Code: Alles auswählen

setattr(self, 'of%s' %xv, Frame(self.root) )

Verfasst: Donnerstag 31. August 2006, 23:41
von Michael Schneider
Hi PyStyler,

nein, mit "gefordert" meine ich eine Anforderung per Spezifikation.

Das wie ich finde größte Problem bei der commerziellen Softwareentwicklung ist häufig, dass eine Gruppe A Anforderungen stellt, die Gruppe B programmiert um dann von Gruppe C praktisch verwendet zu werden. Nun muss aber B genau das programmieren, was A wünscht, auch wenn es besser wüsste, was C tatsächlich will und sich A mal wieder viel zu weit aus dem Fenster lehnt, indem es sich in Dinge einmischt von denen es keine Ahnung hat und demzufolge völlig unnötige Einschränkungen vorgibt (z.B. einfach mal Frames zu verwenden, vielleicht weil das grad so Mode ist...).
Alles klar? Wer schonmal beruflich programmiert hat wird wissen, wovon ich rede. :idea:

Jedenfalls sind getattr und setattr hier völlig überflüssig, weil meiner Meinung viel zu kompliziert dafür, dass man mit einfachen Strukturen klarkommt. Heb Dir das am besten für Wrapper-Klassen und dergleichen auf. :-)

Grüße und gute Nacht,
Michael