Wischfunktion durch Buttonklick hervorrufen
@Alfons Mittelmeyer: das was Du da so verteufelst, weil Du es nicht kennst, nennt sich closure und existiert so in fast jeder modernen Programmiersprache. So lange eine Funktion schön kurz ist, hilft es, umständliches Kopieren von Argumenten in Attribute, die man eigentlich nicht in einer Funktion neu einführen sollte, zu verhindern.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Wieso ist das semantisch keine Klasse? Es ist natürlich eine Klasse. Nur macht so eine Klasse wenig Sinn, wenn man von dieser nur eine einzige Methode benützt. Dann kann man genauso gut eine Funktion nehmen.BlackJack hat geschrieben:@Alfons Mittelmeyer: Das ist semantisch keine Klasse. Das ist nur formal Eine.
Aber wenn man davon ausgeht, dass man das eh nur für einen SwipeFrame braucht, dann ist so ein SwipeFrame natürlich ein Klasse. Wenn man weiter davon ausgeht, dass diese Swipe Fenster alle gleich groß sind, dann kann man auch Größenangaben und Koordinatenangaben in diesen SwipeFrame verlagern.
Also SwipeFrame ist bestimmt eine Klasse:
Code: Alles auswählen
import tkinter as tk
# ---- Definition of SwipeFrame ---------------
class SwipeFrame(tk.Frame):
def __init__(self,master, **kwargs):
kwargs['width']=200
kwargs['height']=150
tk.Frame.__init__(self, master, **kwargs)
self.ydown=300
self.yup=150
self.timestep=3
self.place(y=self.ydown,x=0)
def wish_on(self):
self.wish(self.ydown,self.yup,-1,self.timestep)
def wish_off(self):
self.wish(self.yup,self.ydown,1,self.timestep)
def wish(self,y0, yn, step,timestep):
def do_move(y):
y += step
self.place(y=y)
if y != yn:
self.after(timestep, do_move,y)
do_move(y0)
# ---- GUI ---------------------------------------
class Mainframe(tk.Frame):
def __init__(self,master,**kwargs):
tk.Frame.__init__(self,master,**kwargs)
tk.Label(self, text='Screen',bg=self['bg']).place(y=0,x=0)
tk.Button(self, text='wish on', command=self.wish_on).place(y=243,x=50)
self.button_frame = ButtonFrame(self,bg='#d9d93c')
def wish_on(self):
self.button_frame.wish_on()
class ButtonFrame(SwipeFrame):
def __init__(self, master, **kwargs):
SwipeFrame.__init__(self, master, **kwargs)
tk.Label(self, text='Swipe Window',bg=self['bg']).place(y=0,x=0)
tk.Button(self, text='wish off',command=self.wish_off).place(y=93,x=50)
def main():
app = tk.Tk()
app.geometry("280x370")
mainframe = Mainframe(app, width=200, bg='#d949d9', height=300)
mainframe.place(y=28, x=43)
app.mainloop()
if __name__ == '__main__':
main()
asse:
@Alfons Mittelmeyer: Es ist semantisch keine Klasse. Die Begründung hast Du ja selbst schon geschrieben.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Die Klasse ist syntaktisch richtig. Auch semantisch stimmt sie. Nur pragmatisch ist diese Klasse nicht sinnvoll.BlackJack hat geschrieben:@Alfons Mittelmeyer: Es ist semantisch keine Klasse. Die Begründung hast Du ja selbst schon geschrieben.
Syntaktisch richtig wäre etwa dieses Datum: 29. Februar 2017
Semantisch ist dieses Datum allerdings falsch.
Pragmatisch unklug wäre es, stets nur am 29. Februar jährlich fällige Zahlungen zu leisten.
@Alfons Mittelmeyer: Nein, das ist semantisch keine Klasse. Diese ”Klasse” nimmt keine Aufgabe wahr für die man Klassen verwendet. Darum kann man ja auch so einfach und ohne einen Verlust eine Funktion daraus machen.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Leere BehauptungBlackJack hat geschrieben:@Alfons Mittelmeyer: Nein, das ist semantisch keine Klasse.
Genau solche Aufgaben nimmt sie wahr. So hat man dadurch eine Datenkapselung und braucht keine globalen Variablen verwenden. Dann kann man mehrere Objekte der Klasse erzeugen, wenn etwa nicht hintereinander solche Wish Aktionen erfolgen sollen, sondern ziemlich gleichzeitig.BlackJack hat geschrieben:Diese ”Klasse” nimmt keine Aufgabe wahr für die man Klassen verwendet.
Für den Fall, dass man nicht mehrere Wish-Aktionen gleichzeitig durchführen will, sondern nur immer hintereinander, genügt eine Funktion. Ansonsten braucht man eine Klasse oder etwas, das auch die Eigenschaften einer Klasse besitzt. Für eine Klasse mit nur einer Methode kann man nämlich auch eine "closure" nehmen. Dass man in python eine Klasse mit nur einer Methode auch als closure realisieren kann, ist kein Grund, weshalb eine Klasse mit nur einer Methode keine Klasse sein soll.BlackJack hat geschrieben:Darum kann man ja auch so einfach und ohne einen Verlust eine Funktion daraus machen.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Die Syntax beschreibt die Regeln für richtige Sprachkonstrukte. Bei der Semantik geht es um die Beschreibung, wie der Interpreter den Code ausführen soll. Für Python gibt es allerdings keine systematische formale Beschreibung der Semantik sondern nur ein informelles Handbuch und eine Reihe von Implementationen.BlackJack hat geschrieben:@Alfons Mittelmeyer: Es ist semantisch keine Klasse.
Für ein Subset von Python namans minipy wurde allerdings eine formale Beschreibung der Semantik aufgestellt : Gideon Joachim Smeding - An executable operational semantics for Python
Quelle (PDF 91 Seiten): http://gideon.smdng.nl/wp-content/uploads/thesis.pdf
Darin heißt es etwa:
Vielleicht kapierst Du langsam, was Semantik einer Programmiersprache ist. Wenn ich selber einen Python Interpreter schreiben würde, der sich anders verhielte als in Python üblich, das würde eine Verletzung der Semantik sein.A class definition class x(e) : b creates a new class object. Its bases are set to the value of e, and the variables bound in b define its attributes.
Class definitions are not declarative, like in many other object oriented languages, but imperative in style. The body b and bases e of a new class are executed and evaluated when the class definition is executed.
Before the body is executed, the base objects have to be evaluated. The bases are represented by a tuple expression e.
When e has been evaluated, its result a is stored on the stack.
The body is executed with a new object c on top of the environment stack. All variable bindings within the body will be bound in the object c. Thus attributes of the new class are defined by ordinary variable bindings in the body.
Class definitions that are nested in class definitions, can not access the attributes of the class enclosing them through the environment. If the topmost environment g1 is an object, the body of the class definition is executed without g1 in the environment stack. Nested function definitions are limited in the same way
Und solche Behauptungen wie eine Klasse mit nur einer Methode wäre semantisch keine Klasse, ist absoluter Unsinn. Die Semantik beschreibt, wie der Interpreter eine Klassendefinition abarbeiten soll.
@Alfons Mittelmeyer: Die Klasse nimmt die Aufgabe einer Klasse nicht wahr. Wo ist da Datenkapselung? Bei der Klasse über die ich hier rede hast Du einfach nur die Funktion als Methode in eine Klasse verschoben die `self` nicht benutzt und hast trotzdem behauptet das wäre semantisch eine Klasse. Ist es nicht.
Die Funktion die Du zur ”Methode” gemacht hast kann man auch für mehr als eine Animantion gleichzeitig verwenden, denn sie verwendet ja ein Closure ist aber selbst keins.
Semantik bezog sich auf OOP, nicht auf auf die semantik der Programmiersprache Python. Und objektorientiert gesehen ist eine Klasse die einfach nur eine Funktion als ”Methode” enthält semantisch keine Klasse. Das ist weder eine Unsinn noch ein leere Behauptung.
Die Funktion die Du zur ”Methode” gemacht hast kann man auch für mehr als eine Animantion gleichzeitig verwenden, denn sie verwendet ja ein Closure ist aber selbst keins.
Semantik bezog sich auf OOP, nicht auf auf die semantik der Programmiersprache Python. Und objektorientiert gesehen ist eine Klasse die einfach nur eine Funktion als ”Methode” enthält semantisch keine Klasse. Das ist weder eine Unsinn noch ein leere Behauptung.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Reden wir darüber?BlackJack hat geschrieben:@Alfons Mittelmeyer: Die Klasse nimmt die Aufgabe einer Klasse nicht wahr. Wo ist da Datenkapselung? Bei der Klasse über die ich hier rede hast Du einfach nur die Funktion als Methode in eine Klasse verschoben die `self` nicht benutzt und hast trotzdem behauptet das wäre semantisch eine Klasse. Ist es nicht.
Code: Alles auswählen
class WishClass():
def wish(self,element,y0, yn, step,timestep):
self.element = element
self.yi = y0
self.yn = yn
self.step=step
self.timestep = timestep
self.do_move()
def do_move(self):
self.yi += self.step
self.element.place(y=self.yi)
if self.yi != self.yn:
self.element.after(self.timestep, self.do_move)
Code: Alles auswählen
class WishClass():
def wish(self,element,y0, yn, step,timestep):
def do_move(y):
y += step
element.place(y=y)
if y != yn:
element.after(timestep, do_move, y)
do_move(y0)
Im zweiten Fall ist natürlich eine Klasse nicht sinnvoll, da die Funktion darin durch die Closure auch bereits den Zweck erfüllt. Sinnvoll allerdings wird die Klasse wiederum, wenn wir sie durch weitere Methoden, etwa wish_on, wish_off und __init__ erweitern und auch noch von tk.Frame ableiten, wie ich das dann bei der Klasse SwipeFrame gemacht hatte.
Warum diskutieren wir über noch wenig ausgebaute Anfangszustände, ob die schon eine Klasse sind oder nicht, mit der Zeit wachsen sie sich schon noch aus.
Code: Alles auswählen
class SwipeFrame(tk.Frame):
def __init__(self,master, **kwargs):
kwargs['width']=200
kwargs['height']=150
tk.Frame.__init__(self, master, **kwargs)
self.ydown=300
self.yup=150
self.timestep=3
self.place(y=self.ydown,x=0)
def wish_on(self):
self.wish(self.ydown,self.yup,-1,self.timestep)
def wish_off(self):
self.wish(self.yup,self.ydown,1,self.timestep)
def wish(self,y0, yn, step,timestep):
def do_move(y):
y += step
self.place(y=y)
if y != yn:
self.after(timestep, do_move,y)
do_move(y0)
@Alfons Mittelmeyer: am Anfang war die Klasse aber noch nicht sinnvoll. In Python ist es sehr einfach, aus einer Funktion eine Klasse zu machen, so dass es nicht nötig ist, alles auf Vorrat in eine Klasse zu packen.
Bei Deiner ersten Wunschklasse aus dem letzten Posting wäre es zudem sinnvoll, die Methode wish als __init__ zu schreiben und ihr noch eine start-Methode zu spendieren, weil, wie Du ja öfter schon betont hast, es ja sein kann, dass man mehrere Wünsche gleichzeitig erfüllt haben will, was ja nicht geht, wenn man nur ein WishClass-Exemplar hat, auf dem man mehrmals wish aufruft.
Bei Deiner ersten Wunschklasse aus dem letzten Posting wäre es zudem sinnvoll, die Methode wish als __init__ zu schreiben und ihr noch eine start-Methode zu spendieren, weil, wie Du ja öfter schon betont hast, es ja sein kann, dass man mehrere Wünsche gleichzeitig erfüllt haben will, was ja nicht geht, wenn man nur ein WishClass-Exemplar hat, auf dem man mehrmals wish aufruft.
@Alfons Mittelmeyer: Ich rede von der Klasse bei der ich gesagt habe es wäre semantisch keine und Du behauptet hast es wäre doch eine, und das ist die Wo Du einfach nur die Funktion in eine formale Klasse verschoben hast. Ob sich solche Anfangszustände noch auswachsen oder nicht ist IMHO kein Grund für *den* Zwischenstand, da hätte man auch gleich den nächsten Schritt gehen können bei dem die Klasse einen Sinn hat. Der ist ja auch nicht wirklich weit weg.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Ja, man kann auch wish als __init__ implementieren. Dann würde bei jedem Aufruf ein neues Wishobjekt instanziert werden. Das kann man tun, weil man nicht nicht so ungegeuer viel wisht, dass es den Garbage Collector sehr strapazieren würde. Wenn man allerdings jedem zu verschiebendem Frame ein eigenes Wishobjekt fest zuordnet, dann braucht sich der Garbage Collector nicht um das Aufräumen ständig neu erzeugter Wishobjekte kümmern. Aber das spielt sowieso keine Rolle.Sirius3 hat geschrieben:@Alfons Mittelmeyer: Bei Deiner ersten Wunschklasse aus dem letzten Posting wäre es zudem sinnvoll, die Methode wish als __init__ zu schreiben
Nein, man hätte dann nicht nur ein einziges WishClass-Exemplar sondern jedes Wish-Fenster hätte dann sein eigenes Wish-Exemplar gehabt. Im Endeffekt ist es ja jetzt auch so, weil nämlich jetzt SwipeFrame und Wish-Exemplar identisch sind.Sirius3 hat geschrieben:und ihr noch eine start-Methode zu spendieren, weil, wie Du ja öfter schon betont hast, es ja sein kann, dass man mehrere Wünsche gleichzeitig erfüllt haben will, was ja nicht geht, wenn man nur ein WishClass-Exemplar hat, auf dem man mehrmals wish aufruft.