Frage zu: * vor Funktionsparameter

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
froedi

Sonntag 22. Juni 2003, 19:55

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[++].
joerg
User
Beiträge: 188
Registriert: Samstag 17. August 2002, 17:48
Wohnort: Berlin
Kontaktdaten:

Montag 23. Juni 2003, 07:12

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
lbuega
User
Beiträge: 75
Registriert: Dienstag 15. April 2003, 08:51
Wohnort: Weissach

Dienstag 24. Juni 2003, 08:59

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.
Gast

Dienstag 24. Juni 2003, 11:20

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
Kartoffel
User
Beiträge: 66
Registriert: Montag 7. April 2003, 17:08

Dienstag 24. Juni 2003, 17:08

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'
rAiNm4n
User
Beiträge: 19
Registriert: Mittwoch 4. Juni 2003, 11:30
Wohnort: Berlin

Dienstag 24. Juni 2003, 17:28

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
bombing for freedom is like fucking for virginity
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Dienstag 24. Juni 2003, 17:38

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)
Kartoffel
User
Beiträge: 66
Registriert: Montag 7. April 2003, 17:08

Dienstag 24. Juni 2003, 19:05

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.
joerg
User
Beiträge: 188
Registriert: Samstag 17. August 2002, 17:48
Wohnort: Berlin
Kontaktdaten:

Mittwoch 25. Juni 2003, 12:18

@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
Kartoffel
User
Beiträge: 66
Registriert: Montag 7. April 2003, 17:08

Mittwoch 25. Juni 2003, 12:56

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.
Antworten