Seite 1 von 1

Frage zu: * vor Funktionsparameter

Verfasst: Sonntag 22. Juni 2003, 19:55
von froedi
hi!

ich gebe zu das ist eine komische überschrift, aber ich wusste nicht genau, wie ich das ganze sonst betiteln sollte :wink:

und zwar gibt es in BaseHTTPServer.py eine funktion mit folgender signatur:

def log_message(self, format, *args):

was genau hat es mit diesem sternchen (*) auf sich?
erinnert mich irgendwie an die parameter-übergabe als zeiger in C[++].

Re: Frage zu: * vor Funktionsparameter

Verfasst: Montag 23. Juni 2003, 07:12
von joerg
froedi hat geschrieben:hi!

ich gebe zu das ist eine komische überschrift, aber ich wusste nicht genau, wie ich das ganze sonst betiteln sollte :wink:

und zwar gibt es in BaseHTTPServer.py eine funktion mit folgender signatur:

def log_message(self, format, *args):

was genau hat es mit diesem sternchen (*) auf sich?
erinnert mich irgendwie an die parameter-übergabe als zeiger in C[++].
Das heißt, das die Variable args alle weiteren, nicht bereits zugeordneten Argumente als Tupel enthält. Allerdings nur die Argumente, die ohne Keyword übergeben werden. Mit zwei Sternen heißt es, daß alle noch nicht ausgewerteten Keywordargumente in einen Dictionary gesteckt werden.

Eine Funktion, die mit "def bla(*arg, **kwarg): ..." anfängt, akzeptiert demnach jegliche Anzahl und Kombination von Argumenten, wobei alle Stellungsparamter nachher im Tupel arg und alle Keywordparameter im Dictionary kwarg stecken.

Jörg

Verfasst: Dienstag 24. Juni 2003, 08:59
von lbuega
Wow super; endlich hab ich auch mal verstanden was dieses **kw heißt: Keyword - Vielen Dank.

Kannst Du dafür vielleicht noch ein aussagekräftiges Code-Beispiel posten? Das wär spitze.

Verfasst: Dienstag 24. Juni 2003, 11:20
von Gast
lbuega hat geschrieben:Kannst Du dafür vielleicht noch ein aussagekräftiges Code-Beispiel posten? Das wär spitze.
Guck mal im Tutorial unter 4.7.2 Keyword Arguments. Da ist ein anschauliches Beispiel.
Jan

Verfasst: Dienstag 24. Juni 2003, 17:08
von Kartoffel
Wie kann ich solche Keywordargumente an eine andere Funktion weiterreichen, so ähnlich wie Canvas das macht?
Ich hab mir den entsprechenden Canvas-Quellcode mal angeschaut, bin aber nicht schlau daraus geworden....

Also

Code: Alles auswählen

def f1(**kw):
     ...(das will ich ja wissen)

def f2(arg):
     print arg

f1(arg="Hallo")
'Hallo'

Verfasst: Dienstag 24. Juni 2003, 17:28
von rAiNm4n
Ich kenne Canvas nicht, aber ich könnte mir vorstellen, dass du so etwas meinst:

Code: Alles auswählen

def f1(**kw):
    if kw.has_key('arg'):
        f2(kw['arg'])

def f2(arg):
    print arg

>>> f1(arg="Hallo")
'Hallo'
cu
Chris

Verfasst: Dienstag 24. Juni 2003, 17:38
von Milan
Hi, die Keywordargumente werden wie der Name schon sagt in einem Dictionary gespeichert. Du kannst sie z.B. mit Apply weiterleiten. Apply verlangt eine Funktion, Argumente in Form eines Tupel und Kewordargumente in Form eines Dictionarys:

Code: Alles auswählen

def aufname(*args,**kw):
    apply(ausgabe,args,kw)
def ausgabe (*args,**kw):
    print args
    print kw

aufname(1,2,3,4,5,6,abc="abc",nix="dochetwas",x=1)

Verfasst: Dienstag 24. Juni 2003, 19:05
von Kartoffel
Danke, Milan, das habe ich gesucht :D
Funktioniert scheinbar nur, wenn ich auch noch mit *a nicht Schlüsselwort-gebundene Argumente verwende... -oder mache ich was falsch?

@rAiNm4n: Das Problem bei deiner Lösung ist, dass ich immer noch alle möglichen Parameter behandeln muss, darum bringt es mir eigentlich keinen Vorteil gegenüber der Möglichkeit, alle Parameter in der ersten Funktion explizit abzufragen und dann einzeln weiterzuleiten.

Verfasst: Mittwoch 25. Juni 2003, 12:18
von joerg
@Kartoffel: Das zweite Argumnet zu apply kann doch auch ein leeres Tupel sein, oder meintest Du was anderes?

@all:
Seit einiger Zeit (Python-2.0 ?) gibt es auch eine Alternative zu apply, allerdings verwende ich es auch noch eher selten.

Statt 'foo(a, b, c)' kann man auch 'x = (a,b,c); foo(*x)' schreiben.

Statt 'bar(a=1, b=2)' kann man auch 'x = {'a': 1, 'b':2}; bar(**x)' schreiben.

Sprich: man kann die erhaltenen Tupel und Dictionaries in gleicher Form an eine andere Methode weitergeben, ohne apply:

Code: Alles auswählen

class bla(fasel):
  def __init__(self, *arg, **kwarg):
    fasel.__init__(self, *arg, **kwarg)
    # usw. ...
Jörg

Verfasst: Mittwoch 25. Juni 2003, 12:56
von Kartoffel
joerg hat geschrieben:@Kartoffel: Das zweite Argumnet zu apply kann doch auch ein leeres Tupel sein, oder meintest Du was anderes?
Das hab ich schon so gemeint - ein leeres Tupel ist scließlich auch ein Argument....
War auch weniger ein Problem als eine Feststellung :lol:

Aber die neuere Version gefällt mir fast noch besser, man sieht besser dass es ein Funktionsaufruf ist.