449 Stimmen

Wie kann ich eine Funktion mit optionalen Argumenten definieren?

Ich habe eine Python-Funktion, die mehrere Argumente benötigt. Einige dieser Argumente könnten in manchen Szenarien weggelassen werden.

def some_function (self, a, b, c, d = None, e = None, f = None, g = None, h = None):
    #code

Die Argumente d über h sind Zeichenfolgen, die jeweils unterschiedliche Bedeutungen haben. Es ist wichtig, dass ich wählen kann, welche optionalen Parameter ich in beliebiger Kombination übergeben möchte. Zum Beispiel, (a, b, C, d, e) , oder (a, b, C, g, h) , oder (a, b, C, d, e, f oder alle von ihnen (das sind meine Entscheidungen).

Es wäre toll, wenn ich die Funktion überladen könnte - aber ich habe gelesen, dass Python das Überladen nicht unterstützt. Ich habe versucht, einige der erforderlichen int-Argumente in die Liste einzufügen - und bekam einen Argument-Mismatch-Fehler.

Im Moment sende ich leere Zeichenfolgen anstelle der ersten paar fehlenden Argumente als Platzhalter. Ich möchte eine Funktion nur mit tatsächlichen Werten aufrufen können.

Gibt es eine Möglichkeit, dies zu tun? Kann ich eine Liste anstelle der Argumentliste übergeben?

Im Moment sieht der Prototyp mit ctypes etwa so aus:

_fdll.some_function.argtypes = [c_void_p, c_char_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p]

2voto

Andrew Richards Punkte 1102

Um ein besseres Gefühl dafür zu bekommen, was bei der Übergabe von Parametern möglich ist, ist es sehr hilfreich, sich die verschiedenen Optionen anzusehen: positional-or-keyword ( arg o arg="default_value" ), nur für die Position (vor /, in der Parameterliste), nur das Schlüsselwort (nach *, in der Parameterliste), var-positional (typischerweise *args ) oder var-keyword (typischerweise **kwargs ). In der Python-Dokumentation finden Sie eine ausgezeichnete Zusammenfassung In den verschiedenen anderen Antworten auf die Frage werden die meisten dieser Varianten verwendet.

Da Sie in Ihrem Beispiel immer die Parameter a, b, c haben und sie anscheinend positionsbezogen aufrufen, könnten Sie dies expliziter machen, indem Sie hinzufügen /, ,

def some_function (self, a, b, c, /, d = None, e = None, f = None, g = None, h = None):
    #code

1voto

wayne Punkte 11

Damit die Antwort von Avión auch für Vektorargumente funktioniert;

def test(M,v=None):
    try: 
        if (v==None).all() == False:
            print('argument passed')
            return M + v 
    except: 
        print('no argument passed')
        return M 

Dabei ist M eine Matrix und v ein Vektor. Sowohl test(M) als auch test(M,v) erzeugen Fehler, wenn ich versuche, if-Anweisungen ohne "try/ except"-Anweisungen zu verwenden.

Wie von cem erwähnt, würde ein Upgrade auf Python 3.10 die union (x|y) (oder die Optional[...])-Funktionalität ermöglichen, die einige Türen für alternative Methoden öffnen könnte, aber ich verwende Anaconda spyder, also muss ich wohl auf eine neue Version warten, um Python 3.10 zu verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X