2012-04-12 10 views
1

Was genau ist der Zweck des "formalen Parameters der Form ** Schlüsselwort"? Ich habe es in Anführungszeichen gesetzt, weil es so heißt, wie in den Dokumenten, aber ich hatte Schwierigkeiten, Informationen darüber zu finden und dachte, dass es vielleicht einen formellen Begriff dafür gibt.Formaler Parameter der Form ** Schlüsselwort

Von dem, was ich verstehe, es ermöglicht dem Benutzer so etwas wie

def foo(**keywords): 
    for i in keywords: 
     print(i, ":", keywords[i]) 

foo(val1="1", val2="2", val3="3") 

Ausgang zu tun:

val1 : 1 
val2 : 2 
val3 : 3 

Was genau der Vorteil ist das? Würde eine Wörterbuchvariable nicht besser funktionieren, um das Verständnis zu erleichtern?

+0

Wo genau in den Dokumenten sehen Sie es so genannt? Link bitte. – agf

+0

@agf [py2.x docs] (http://docs.python.org/tutorial/controlflow.html#keyword-arguments) [py3.x docs] (http://docs.python.org /py3k/tutorial/controlflow.html#default-argument-values) – Preom

+1

"formaler Parameter" bezieht sich auf einen Parameter, wie er in der Funktionsdefinition erscheint, und nicht auf den Wert, der diesem Parameter zugeordnet ist, wenn die Funktion aufgerufen wird - der "tatsächliche Parameter". Also "formaler Parameter der Form ..." bedeutet nur "** Schlüsselwort, wenn es als Funktionsparameter verwendet wird". Das ist nicht Teil des Namens dieser Art von Argument. – agf

Antwort

2

Wenn Sie ein Wörterbuch verwenden, wie dies eine Funktion aufrufen aussehen:

myfunv({"key1": "value1", "key2": "value2"}) 

Mit ** kwargs dies wird

myfunc(key1="value1", key2="value2") 

Viele Menschen letztere bevorzugen.

Dieses Konstrukt ist auch sehr nützlich, wenn Sie Argumente transparent an eine andere Funktion oder Klasse übergeben. Zum Beispiel verwende ich dies sehr, wenn ich Tkinter-Widgets unterklassiere.Ich möchte alle Optionen der Basisklasse unterstützen, so dass ich es wie folgt Code:

class MyFrame(tk.Frame): 
    def __init__(self, *args, **kwargs): 
     tk.Frame.__init__(self, *args, **kwargs) 
     <more code here> 

Dies ermöglicht es mir, ohne die gleichen Argumente zu unterstützen, die ausdrücklich alle aufzuzählen.

0

Mit diesem Konstrukt kann der Aufrufer Standardschlüsselwortargumente verwenden.

+0

Was meinst du? –

+1

Der Aufrufer kann Schlüsselwortargumente verwenden, als ob Sie sie in Ihrer Funktionsdefinition als "normal" definiert hätten, ohne dass Sie wissen müssen, dass Sie auf andere Weise darauf zugreifen. –

+0

Oh, ich verstehe es jetzt, danke. –

1

Eine Verwendung ist, wenn Sie Parameter weiterleiten möchten. Zum Beispiel:

def do_some_work(kwd1=None, kwd2=None, ...): 
    .... 

def intermediate_function(some_other_params, **kwargs): 
    ... 
    do_some_work(**kwargs) 

def main(): 
    intermediate_function(some_other_params, kwd1=5, kwd2='foo') 

diese Weise, wenn Sie einen Parameter do_some_work hinzufügen möchten, müssen Sie sich nicht fügen sowohl die Definition von intermediate_function und dem Aufruf von do_some_work innerhalb dort.


Ein anderer Ort, an dem es benutzt wird, ist in Djangos Signalhandlern. Wenn Sie einen Handler schreiben, schreiben Sie es in Form

def handle_signal(sender, instance, **kwargs): 

so dass die API zusätzliche Argumente geändert werden kann in der Zukunft passiert ohne dass die Anwender Methoden zu gehen hinzufügen Parameter zu einem Haufen, die nicht verwenden Sie.

0

Historisch Parameterübergabe wurde entweder durch Position oder über Schlüsselwortargument durchgeführt. komplexe Objekte als Parameter übergeben ist eine relativ neue Hinzufügung und die Leute sind bequemer nebenbei Werte als Parameter

  1. Seine einfache
  2. Ablesbarkeit

nun das Konzept, vorbei variable Positions und Schlüsselwörter Argumente erstreckt, wenn unterstützt führt zu dem obigen Konstrukt.

Interessanterweise ist das Durchlaufen eines Wörterbuchs zwar immer noch möglich, aber die Absicht wird weniger offensichtlich, was der verantwortliche Programmierer nicht möchte.