Ich hab das schon bei einigen Funktionen bemerkt, weiß aber nicht wie ich sowas für meine eigenen Funktionen machen kann:
fkt ( a [, b ] )
So sieht es aus, aber wenn ich es einfach nach diesem Muster abschreibe bekomme ich eine Fehlermeldung.
Kann mir jemand sagen, wie ich sowas machen kann?
Optionale Argumente
Du musst der Variable schon bei erstellung der Funktion einen Wert zuweisen
oder
Code: Alles auswählen
def meine_Funktion(a, b=1):
print a + b
Code: Alles auswählen
def func (a, b=None):
if b == None:
print "Nur a wurde übergeben"
else:
print a, b
Hallo!
Jan
Das hast Du aber garantiert nicht in ausführbarem Code gesehen, sondern nur in der Dokumentation der Funktion. Die eckigen Klammern informieren nur den Leser der Doku darüber, dass das innerhalb der eckigen Klammern optional ist.Kartoffel hat geschrieben:fkt ( a [, b ] )
Jan
Ich habs in der Dokumentation gelesen und in der info die in IDLE angezeigt wird, wenn ich in der Klammer eines Funktionsaufrufs bin. (zeigt die Parameter an, die man der Fkt. übergeben kann)
Ist mir bis jetzt nur in built-in-Funktionen aufgefallen, außerdem ist noch eine Besonderheit dabei:
Bei f(a[,b[,c]]) kann man beispielsweise c nur eingeben, wenn man auch b eingegeben hat.
Ist mir bis jetzt nur in built-in-Funktionen aufgefallen, außerdem ist noch eine Besonderheit dabei:
Bei f(a[,b[,c]]) kann man beispielsweise c nur eingeben, wenn man auch b eingegeben hat.
Ja, das ist noch eindeutig. Nutzt man die 'äußere' Option, so ist b Pflicht und c wiederum optional. Ließe sich beliebig verschachteln.Kartoffel hat geschrieben:Bei f(a[,b[,c]]) kann man beispielsweise c nur eingeben, wenn man auch b eingegeben hat.
Bei aber zum Beispiel range([start,] stop[, step]) ist Schluss mit Logik. Man sieht zwar, dass "start" und "step" optional sind, aber nicht, dass bei Angabe von "step" zwingend "start" angegeben sein muss. Die Notation mit den eckigen Klammern hat also auch so ihre Grenzen.
Jan
muss ich dir wiedersprechen...Kartoffel hat geschrieben:Bei f(a[,b[,c]]) kann man beispielsweise c nur eingeben, wenn man auch b eingegeben hat.
Code: Alles auswählen
>>> def f(a,b=0,c=0):
print a,b,c
>>> f(1,c=3)
1 0 3
Es ging ja auch eher um die Notation in der Doku. Wenn dort file(filename[, mode[, bufsize]]) steht, musst Du bei der Angabe von 'bufsize' auch zwingend 'mode' angeben. Der Aufruf file("bla.txt",bufsize=1024) funktioniert natürlich nicht, da 'bufsize' ja nicht wirklich ein Bezeichner der Funktion file() ist.Milan hat geschrieben:muss ich dir wiedersprechen...
Jan
Eben, darum ist es ja auch nicht das selbeMilan hat geschrieben:muss ich dir wiedersprechen...Kartoffel hat geschrieben:Bei f(a[,b[,c]]) kann man beispielsweise c nur eingeben, wenn man auch b eingegeben hat.Code: Alles auswählen
>>> def f(a,b=0,c=0): print a,b,c >>> f(1,c=3) 1 0 3
Ich glaub', der Groschen ist noch nicht gefallen ist, oder ?Kartoffel hat geschrieben:Eben, darum ist es ja auch nicht das selbe
Eine Funktion die mit f(a[,b[,c]]) dokumentiert wird, könnte als def f(a,b=0,c=0): pass implementiert sein, oder aber auch als def f(a,*args): pass.
Die eckigen Klammen sind keine Python-Syntax, sondern nur eine übliche Art, in Beschreibungen von Funktionen/Methoden (also nur in der Doku) optionale Argumente als solche kenntlich zu machen.
Jan
Bist du dir da sicher?
Nehmen wir zum Beispiel range([start,]stop[,step])
wenn ich ihm nur ein Argument übegebe, ist es stop.
Wenn ich das als def range(start=None, stop, step=None): definieren würde, würde ich schon bei der Definition einen Syntax-Error bekommen.
Ausserdem kann ich die Sache mit den verschactelten eckigen Klammern, die ich schon angesprochen habe auch nicht mit einer Standardzuweisung in der Definition erledigen.
Und ich kenne auch keinen Weg, die Anzeige der Dokumentation zu ändern, es sind immer alle Argumente in der ersten und ggf. ein Docstring in der zweiten Zeile.
Wenn du mir das alles erklären kannst, glaube ich dir, versprochen
Nehmen wir zum Beispiel range([start,]stop[,step])
wenn ich ihm nur ein Argument übegebe, ist es stop.
Wenn ich das als def range(start=None, stop, step=None): definieren würde, würde ich schon bei der Definition einen Syntax-Error bekommen.
Ausserdem kann ich die Sache mit den verschactelten eckigen Klammern, die ich schon angesprochen habe auch nicht mit einer Standardzuweisung in der Definition erledigen.
Und ich kenne auch keinen Weg, die Anzeige der Dokumentation zu ändern, es sind immer alle Argumente in der ersten und ggf. ein Docstring in der zweiten Zeile.
Wenn du mir das alles erklären kannst, glaube ich dir, versprochen
Und zwar weil Parameter ohne Defaultwert grundsätzlich nicht hinter Parametern mit Defaultwerten stehen dürfen. Deshalb lässt sich hier diese "Eckige-Klammern-Notation" nicht mit Default-Parametern realisieren. Bei f(a[,b[,c]]) geht es, weil alle optionalen Parameter hinten vereint stehen.Wenn ich das als def range(start=None, stop, step=None): definieren würde, würde ich schon bei der Definition einen Syntax-Error bekommen.
In der Doku: f(a[,b[,c]]) Implementiert als: def f(x,y=0,z=0): passAusserdem kann ich die Sache mit den verschactelten eckigen Klammern, die ich schon angesprochen habe auch nicht mit einer Standardzuweisung in der Definition erledigen.
Geht doch wunderbar: Der Anwender der Funktion erkennt anhand der eckigen Klammern, dass er die Funktion mit z.B. f(6), f(6,1) oder f(6,1,4) aufrufen kann. Die Implementation spielt da mit. def f(x,*args): pass hätte aber auch funktioniert.
Darum geht's Dir! Sorry, das war mir nicht klar. Also, bei den string-Funktionen ist das einfach so gelöst, dass der 1. Doc-String eben die "Eckige-Klammer-Notation" enthält.Und ich kenne auch keinen Weg, die Anzeige der Dokumentation zu ändern, es sind immer alle Argumente in der ersten und ggf. ein Docstring in der zweiten Zeile.
Code: Alles auswählen
# Join fields with optional separator
def join(words, sep = ' '):
"""join(list [,sep]) -> string
...
"""
return sep.join(words)
Jan
So ganz bin ich immer noch nicht überzeugt:
Dass ich Default-Argumente nicht hinter nicht-Defaults packen darf, weiß ich. Deshalb wundere ich mich ja auch wie das bei range funktioniert.
Bei def f(a, b=None, c=None) kann ich aber auch einen Aufruf f(1, c=2) machen, das geht mit den verschachtelten Klammern nicht.
(Nagut, da könnte ich mir etwas in der Art vorstellen, dass ein Fehler ausgelöst wird, wenn b==None und c!=None)
Der Docstring ist auch gar nicht so wichtig - mich interessiert nur wie man ein entsprechendes Verhalten hinbekommt.
Dass ich Default-Argumente nicht hinter nicht-Defaults packen darf, weiß ich. Deshalb wundere ich mich ja auch wie das bei range funktioniert.
Bei def f(a, b=None, c=None) kann ich aber auch einen Aufruf f(1, c=2) machen, das geht mit den verschachtelten Klammern nicht.
(Nagut, da könnte ich mir etwas in der Art vorstellen, dass ein Fehler ausgelöst wird, wenn b==None und c!=None)
Der Docstring ist auch gar nicht so wichtig - mich interessiert nur wie man ein entsprechendes Verhalten hinbekommt.
Hi, ich muss Voges mal Beistand leisten (;)), dass was er sagt stimmt schon. Allgemein werden Funktionen mit begrenzter Anzahl optionaler Parameter so definiert: def f(a=None,b=None,c=None).
bei f(1,c=2) wird nur ein Spezialfall von den Keywordargumenten genutzt, weil es ja einen fest definierten Parameter c gibt. Range dagegen ist ein Sonderfall, es ist eine Builtin-Funktion. Du könntest ein ähnliches Verhalten intern in der Funktion realisieren, beispielsweise so:
bei f(1,c=2) wird nur ein Spezialfall von den Keywordargumenten genutzt, weil es ja einen fest definierten Parameter c gibt. Range dagegen ist ein Sonderfall, es ist eine Builtin-Funktion. Du könntest ein ähnliches Verhalten intern in der Funktion realisieren, beispielsweise so:
Code: Alles auswählen
def my_range(start,stop=None,step=1):
if stop==None:
stop=start
start=0
...#jetzt gehts normal weiter...
Zuletzt geändert von Milan am Freitag 27. Juni 2003, 05:26, insgesamt 1-mal geändert.
Wie es geht, hat Milan gezeigt. range() ist ja BuildIn, so das man sich das nicht angucken kann. Aber in \Lib\random.py gibt es die Funktion randrange([start,] stop[, step]), die so ungefähr implementiert ist.Kartoffel hat geschrieben:Deshalb wundere ich mich ja auch wie das bei range funktioniert.
Kannst Du nochmal insich geschlossen erläutern, was Du erreichen möchtest? Vielleicht an einem Beispiel. Im allerersten Beitrag schreibst Du was von einer Fehlermeldung.Der Docstring ist auch gar nicht so wichtig - mich interessiert nur wie man ein entsprechendes Verhalten hinbekommt.
Jan
Was konkretes hatte ich eigentlich (noch) nicht vor. Ich wollte nur wissen, wie so eine Funktion aufgebaut ist und wie ich ein Verhalten wie in den Builtins erreiche.
Die Fehlermeldung von der ich am Anfang gesprochen habe, ist die die man bekommt, wenn man versucht eine Funktion mit solchen Eckigen Klammern so zu definieren, wie man es in der Doku der Builtins sieht.
Da ich inzwischen (endlich?) davon überzeugt bin, dass ihr recht habt, hat sich mein Problem schon erledigt.
Die Fehlermeldung von der ich am Anfang gesprochen habe, ist die die man bekommt, wenn man versucht eine Funktion mit solchen Eckigen Klammern so zu definieren, wie man es in der Doku der Builtins sieht.
Da ich inzwischen (endlich?) davon überzeugt bin, dass ihr recht habt, hat sich mein Problem schon erledigt.