Forward Declarations
Verfasst: Freitag 4. August 2006, 11:13
Kann ich meine Funktionen deklarieren, so, dass ich sozusagen die Funktion bekannt gebe, sie aber erst weiter unten im Programm auscodieren kann?
Seit 2002 Diskussionen rund um die Programmiersprache Python
https://www.python-forum.de/
Code: Alles auswählen
def spam():
return ham()
def ham():
return 42
Code: Alles auswählen
def spam():
return ham()
print spam()
def ham():
return 42
Nein. Falls das jemand erwarten würde, dann liegt das vielleicht daran, dass er ``def`` fälschlicherweise als Deklaration ansieht. ``def`` ist aber eine ausführbare Anweisung wie ``print``. Hier wird nach dem kompilieren erst das ``def spam():`` ausgeführt und dann das ``print spam()``. Zu dem Zeitpunkt wurde noch nichts ausgeführt, was den Namen `ham` an ein aufrufbares Objekt bindet, darum gibt's einen `NameError`.CrackPod hat geschrieben:Das würde dann aber nicht gehen, oder?Code: Alles auswählen
def spam(): return ham() print spam() def ham(): return 42
Das ist aber auch keine bessere Lösung. Nicht jedes Problem braucht eine Klasse (gottseidank)!Mad-Marty hat geschrieben:Nimm klassen, da gibts das problem garnicht erst.
Code: Alles auswählen
class dummy:
def spam(self):
return self.ham()
def ausgabe(self):
print self.spam()
def ham(self):
return 42
dummy().ausgabe()
Code: Alles auswählen
def dummy(s): print "Guter", s ## erste Deklaration
dFunktionen = { "ausgabe": dummy } ## in globales Objekt aufnehmen
def ausgabe(s): dFunktionen["ausgabe"](s) ## aktuell referenzierte Funktion ausfuehren
ausgabe("Bulle") ## Testausgabe
def dummy(s): print "Boeser", s ## Neudeklaration
dFunktionen["ausgabe"] = dummy ## uebergabe an globales Objekt
ausgabe("Bulle") ## gleiches Argument an gleiche Funktion, aber ohoo...
Code: Alles auswählen
#######################
## funktioniert nicht!
def ausgabe(a): print "denkste" ## Funktion mit Code definieren
funk = ausgabe ## Namen an Callback-Variable geben
def ausgabe(a): print a ## Funktionscode aendern
funk("Hallo Welt!") ## welche Funktion wird ausgefuehrt?
#######################
## so geht es
f = None ## Funktionsnamen initialisieren
def ausgabe(a): f(a) ## Wrapperfunktion ruft Funktion (Argumente!)
funk = ausgabe ## Namen an Callback-Variable geben
def f(a): print a ## Funktion ausformulieren
funk("Hallo Welt!") ## jetzt wird die aktualisierte Funkt. gerufen
Code: Alles auswählen
def ausgabe(a, f=f)
Und welches "Problem" löst das jetzt genau? Ohne die Klasse, mit den Methoden als Funktionen auf Modulebene funktioniert's genau so, nur das man sich die überflüssige Klasse spart:Michael Schneider hat geschrieben:bei Klassen kann man auf alle im Körper der Klasse definierten Funktionsnamen unter Verwendung der automatisch übergebenen eigenen Objektreferenz zugreifen.
Code: Alles auswählen
class dummy: def spam(self): return self.ham() def ausgabe(self): print self.spam() def ham(self): return 42 dummy().ausgabe()
Code: Alles auswählen
def spam():
return ham()
def ausgabe():
print spam()
def ham():
return 42
ausgabe()
Code: Alles auswählen
class A:
load = staticmethod(load)
def load(self, filename):
pass
a = A()
Das jedoch schonMichael Schneider hat geschrieben: bei Klassen kann man auf alle im Körper der Klasse definierten Funktionsnamen unter Verwendung der automatisch übergebenen eigenen Objektreferenz zugreifen.
In diesem Fall bringt die Klasse keinen Vorteil und ich würde die Funktionen auch vorziehen. Aber in vielen (komplexeren) Fällen ist die strukturelle Kapselung in Klassen eben übersichtlicher. Muss man von Fall zu Fall entscheiden.BlackJack hat geschrieben:Code: Alles auswählen
class A: load = staticmethod(load) def load(self, filename): pass a = A()