Funktionen in Python nur am Anfang
Hallo,
ich bin neu her und wage gerade meine ersten Schritte in Python unter Linux.
Früher hab ich ein bisschen mit C rumgespielt und diverse Sachen unter Windows mit "Pure Basic" gemacht.
Und jetzt also Python - schaun wir mal!
In C und Pure Basic konnte ich Funktionen ans Ende des Sourcecodes stellen
und mit "declare" am Anfang deklarieren. Geht das bei Python auch oder muß die Funktion am Anfang des Source stehen?
Im "byteofpython_120.pdf" konnte ich bisher dazu nichts finden (oder hab es überlesen!)
Für Antworten im voraus herzlichen Dank!
ich bin neu her und wage gerade meine ersten Schritte in Python unter Linux.
Früher hab ich ein bisschen mit C rumgespielt und diverse Sachen unter Windows mit "Pure Basic" gemacht.
Und jetzt also Python - schaun wir mal!
In C und Pure Basic konnte ich Funktionen ans Ende des Sourcecodes stellen
und mit "declare" am Anfang deklarieren. Geht das bei Python auch oder muß die Funktion am Anfang des Source stehen?
Im "byteofpython_120.pdf" konnte ich bisher dazu nichts finden (oder hab es überlesen!)
Für Antworten im voraus herzlichen Dank!
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Du musst Funktionen vor deren Verwendung definieren, am Anfang stehen muessen sie deshalb nicht.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Dies geht nicht:
Dies aber schon:
Stefan
Code: Alles auswählen
geht_nicht()
def geht_nicht():
print "ich werde nicht gefunden"
Code: Alles auswählen
def ich_kann():
die_andere_funktion_aufrufen()
def die_andere_funktion_aufrufen():
print "ich werde gefunden"
ich_kann()
Ok, das war dann ein Fehler von mir, das als "deklariert" zu bezeichnen.derdon hat geschrieben:Funktionen können (wie alle anderen Objekte in Python auch) nicht *deklariert* werden.
In Pure Basic gab's halt das Schlüsselwort "declare", was ich dann auf "deklariert" übernommen habe!
Ich find's bloß ganz angenehm, wenn eine Funktion (oder Prozedur in Pure Basic) am Ende des Source steht.
Auf der anderen Seite hatte ich bisher wenig am Hut mit OO-Programmierung. OKay, meine Frage war ein Schnellschuß (nach Entdeckung von "Import") - kommt nicht nochmal vor!
Bzw. noch näher an C:
Die letzten beiden Zeilen siehst Du so oder so ähnlich recht häufig in Python-Skripten. Sie bedeuten: Rufe "main()" auf, wenn das Skript direkt aufgerufen und nicht nur von einem anderen Skript als Modul eingebunden wurde.
Gruß
Code: Alles auswählen
def main():
andere_funktion()
def andere_funktion():
print "ich werde gefunden."
if __name__ == "__main__":
main()
Gruß
@zenker: Du hast das was Du möchtest schon richtig als "deklariert" beschrieben. Nur gibt's in Python halt (fast) keine Deklarationen. Du kannst Funktionen "nur" definieren.
Das ist nur indirekt eine Frage der Position im Quelltext. Du kannst zur Laufzeit ein Objekt erst verwenden, wenn es vorher definiert wurde. Macht ja auch irgendwie Sinn. Definitionen passieren zur Laufzeit und der Code auf Modulebene wird von oben nach unten ausgeführt.
Das ist nur indirekt eine Frage der Position im Quelltext. Du kannst zur Laufzeit ein Objekt erst verwenden, wenn es vorher definiert wurde. Macht ja auch irgendwie Sinn. Definitionen passieren zur Laufzeit und der Code auf Modulebene wird von oben nach unten ausgeführt.
Allerdings:sma hat geschrieben: Dies aber schon:StefanCode: Alles auswählen
def ich_kann(): die_andere_funktion_aufrufen() def die_andere_funktion_aufrufen(): print "ich werde gefunden" ich_kann()
Code: Alles auswählen
def ich_kann():
die_andere_funktion_aufrufen()
def die_andere_funktion_aufrufen(ich_kann):
print "ich werde gefunden"
ich_kann()
Nochmal ausführlich: Ich habe zwei Funktionen A und B. Funktion B ist von A abgeleitet und überschreibt ein Attribut. In Klasse A möchte ich nun an einer Stelle Klasse B aufrufen. Egal wie rum ich es auch drehe, es funzt leider nicht.
Kann wer helfen?
Danke & Grüße
In dem Fall meckert der Interpreter nur darüber, dass "die_andere_.." ein Argument verlangt, was du ihr bei Aufruf in "ich_kann" nicht übergibst.J.D. hat geschrieben:Allerdings:sma hat geschrieben: Dies aber schon:StefanCode: Alles auswählen
def ich_kann(): die_andere_funktion_aufrufen() def die_andere_funktion_aufrufen(): print "ich werde gefunden" ich_kann()
Code: Alles auswählen
def ich_kann(): die_andere_funktion_aufrufen() def die_andere_funktion_aufrufen(ich_kann): print "ich werde gefunden" ich_kann()
Ich bin mir momentan nicht ganz sicher, ob ich das Problem wirklich verstanden habe, aber so etwas geht ohne Probleme:J.D. hat geschrieben:Nochmal ausführlich: Ich habe zwei Funktionen A und B. Funktion B ist von A abgeleitet und überschreibt ein Attribut. In Klasse A möchte ich nun an einer Stelle Klasse B aufrufen. Egal wie rum ich es auch drehe, es funzt leider nicht.
Code: Alles auswählen
class foo(object):
def do_it(self):
self.make_it()
class bar(foo):
def make_it(self):
self.x = self.x + 1
baz = bar()
baz.x = 1
baz.do_it()
print baz.x
Ich glaube, du hast noch nicht ganz verstanden, was Klassen, Funktionen, Methoden und Attribute sind. Du kannst nicht von einer Funktion erben oder ableiten, falls du das mit diesem Code errreichen wolltest:
Code: Alles auswählen
def ich_kann(): die_andere_funktion_aufrufen() def die_andere_funktion_aufrufen(ich_kann): print "ich werde gefunden" ich_kann()
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Kann es sein, dass du Klassen und Funktionen nicht auseinander halten kannst? Bitte beschreibe einmal ausfuehrlich, _was genau_ du machen willst, nicht die Mittel, um das zu erreichen.J.D. hat geschrieben:Ich habe zwei Funktionen A und B. Funktion B ist von A abgeleitet und überschreibt ein Attribut. In Klasse A möchte ich nun an einer Stelle Klasse B aufrufen.
Kurzerklaerung (ohne Designueberlegungen, die aber vllt das wichtigste bei Klassen sind):
Funktionen haben Argumente, stellen mit diesen etwas an und geben das Ergebnis zurueck.
Klassen haben ein ``__init__`` und das uebernimmt Argumente und gibt eine Instanz/Exemplar der Klasse zurueck, dass dann eigenstaendig "lebt". Von Klassen kann man erben, d.h. alle Namen der Basisklasse sind in der erbenden Klasse vorhanden (bis sie evtl ueberschrieben werden).
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Erst mal ein Dankeschön für die Hilfe von euch.
Anscheinend waren meine Finger wieder schneller als die Augen.
Der Code von /me trifft es schon relativ genau. So sieht das bei mir aus:
So sieht das ungefähr aus. Eventuell gibt es auch eine elegantere Möglichkeit (z.B. mit echter Rekursion) aber mich interessiert jetzt auch mal speziell dieses Problem. Eure Beispiele oben funktionieren, das glaube ich. Aber anscheinend sieht die Sache anders aus, sobald Vererbung ins Spiel kommt. Bin offen für Vorschläge.
Anscheinend waren meine Finger wieder schneller als die Augen.
Der Code von /me trifft es schon relativ genau. So sieht das bei mir aus:
Code: Alles auswählen
class foo(object):
"""Validierung mit Hilfe von Validatorklasse. bar() ist z.B. eine Validatorklasse"""
value1 = validator.(ValidatorKlasse1())
value2 = validator.(ValidatorKlasse2())
value3 = validator.(bar()) # Hier tritt das Problem auf, die Subklasse kann nicht aufgerufen werden, weil Python sie angeblich nicht kennt.
class bar(foo):
""" von foo abgeleitet. überschreibt value3 um endlose rekursion zu vermeiden. """
value3 = None
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Das Problem taucht aber nicht erst in ``bar`` auf, sondern schon in ``foo``, wenn du ``bar`` wirklich in ``foo`` brauchst, solltest du das dem Aufruf von ``foo`` als Argument uebergeben.
Ist das eigentlich Absicht, dass das alles Klassenvariablen sind?
Ist das eigentlich Absicht, dass das alles Klassenvariablen sind?
Code: Alles auswählen
class foo(object):
def __init__(ValidatorKlasse1, ValidatorKlasse2, ValidatorKlasse3):
value1 = validator.(ValidatorKlasse1())
value2 = validator.(ValidatorKlasse2())
value3 = validator.(ValidatorKlasse3())
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Ich verstehe nicht ganz, was du da wirklich machen willst, aber wo kommt da jetzt "validator" her?
@cofi: was soll dein Beispiel da jetzt bewirken - so wird das bestimmt nicht funktionieren? Vllt. verstehe ich da auch was falsch...^^
@cofi: was soll dein Beispiel da jetzt bewirken - so wird das bestimmt nicht funktionieren? Vllt. verstehe ich da auch was falsch...^^
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Erm ja ... danke. Ich bin noch vor dem ersten Kaffee.SchneiderWeisse hat geschrieben:@cofi: was soll dein Beispiel da jetzt bewirken - so wird das bestimmt nicht funktionieren?
Code: Alles auswählen
class foo(object):
def __init__(ValidatorKlasse1, ValidatorKlasse2, ValidatorKlasse3):
value1 = ValidatorKlasse1()
value2 = ValidatorKlasse2()
value3 = ValidatorKlasse3()
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Das mit den Validatoren war nur beispielhaft (weil mein Code zur Validierung von Objekten dienen soll) und verwirrt hier vielleicht mehr, als dass es hilft. Zudem habe ich mich offenbar schon wieder vertippt (Schande über mich): Der Punkt bei validators ist natürlich Unsinn.
Ich möchte nicht ausschließen, dass sich der Code noch stark optimieren lässt, da ich selbst blutiger Anfänger in Python bin (komme aus der Java-Ecke).
In Java wäre mein Beispiel kein Problem, da Klassen zumeist in eigenen Dateien zu finden sind und nicht in Modulen zusammengefasst werden, in denen dann die Reihenfolge offenbar schon eine Rolle spielt (zumindest wenn man mit Vererbung arbeitet.
Das Problem an meinem Beispiel ist einfach: Klasse B muss Klasse A kennen (da B Kind von A ist), aber Klasse A muss auch B kennen (da B in A verwendet wird). Meiner Meinung nach geht das nicht, falls nicht eine der beiden Klassen explizit der anderen übergeben wird (was in meinem Beispiel nicht der Fall ist).
Das mit den Validatoren ist eher nebensächlich, sorry dafür. Aber ja: validators() ist eine Funktion, der ich eine Klasse übergebe.
Ich möchte nicht ausschließen, dass sich der Code noch stark optimieren lässt, da ich selbst blutiger Anfänger in Python bin (komme aus der Java-Ecke).
In Java wäre mein Beispiel kein Problem, da Klassen zumeist in eigenen Dateien zu finden sind und nicht in Modulen zusammengefasst werden, in denen dann die Reihenfolge offenbar schon eine Rolle spielt (zumindest wenn man mit Vererbung arbeitet.
Das Problem an meinem Beispiel ist einfach: Klasse B muss Klasse A kennen (da B Kind von A ist), aber Klasse A muss auch B kennen (da B in A verwendet wird). Meiner Meinung nach geht das nicht, falls nicht eine der beiden Klassen explizit der anderen übergeben wird (was in meinem Beispiel nicht der Fall ist).
Das mit den Validatoren ist eher nebensächlich, sorry dafür. Aber ja: validators() ist eine Funktion, der ich eine Klasse übergebe.
@J.D.: Kannst Du das eventuell mit Sinn füllen? Warum willst Du so eine komische Beziehung haben? Ich fände das auch unter Java eigenartig. Kannst Du keine Gemeinsamkeiten in eine dritte Klasse auslagern?
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Code: Alles auswählen
>>> class A(object):
... def __init__(self):
... self.b = B()
...
>>> class B(A):
... def __init__(self):
... pass
...
>>> a = A()
>>> b = B()
>>> a
<__main__.A object at 0xb7e5b84c>
>>> a.b
<__main__.B object at 0xb7e5b62c>
Bottle: Micro Web Framework + Development Blog
@Defnull: Zumindest den Beispielen nach soll `B` anscheinend bei `A` schon bei der Klassendefinition von `A` als bzw. für ein Klassenattribut verwendet werden.