Wie gebe ich mehrere Werte von einer Funktion?

Der übliche Weg, um mehrere Werte zurückgeben, die in Sprachen, die es unterstützen, ist oft tupling.

Option: Mit einem Tupel

Betrachten Sie dieses einfache Beispiel:

def f(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return (y0, y1, y2)

Jedoch, das wird schnell problematisch wird, da die Anzahl der zurückgegebenen Werte erhöht. Was, wenn Sie zurückkehren möchten, vier oder fünf Werte? Sicher, man könnte immer tupling, aber es wird leicht vergessen, welcher Wert wo. Es ist auch eher hässlich entpacken Sie Sie, wohin Sie wollen, Sie zu empfangen.

Option: eine Wörterbuch -

Der nächste logische Schritt zu sein scheint, die Einführung einer Art "record-notation'. In Python, die offensichtliche Weg, dies zu tun ist durch eine dict.

Folgendes:

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0': y0, 'y1': y1 ,'y2': y2}

(Nur um klar zu sein, y0, y1 und y2 dienen nur als abstrakte Bezeichner. Wie hingewiesen, in der Praxis würden Sie verwenden Sie sinnvolle Bezeichner.)

Nun, wir haben einen Mechanismus, durch den wir Projekt aus einem bestimmten Mitglied des zurückgegebenen Objekts. Zum Beispiel,

result['y0']

Option: Verwendung einer Klasse

Allerdings gibt es eine weitere option. Wir könnten stattdessen Rückkehr eine spezialisierte Struktur. Ich habe gerahmt, diese in den Kontext von Python, aber ich bin sicher, es gilt auch für andere Sprachen. In der Tat, wenn Sie arbeiten wurden in C das könnte sehr gut sein, Ihre einzige option. Hier geht:

class ReturnValue:
  def __init__(self, y0, y1, y2):
     self.y0 = y0
     self.y1 = y1
     self.y2 = y2

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return ReturnValue(y0, y1, y2)

In Python die beiden vorherigen sind vielleicht sehr ähnlich in Bezug auf Sanitär -, nachdem alle { y0, y1, y2 } nur am Ende als Einträge im internen __dict__ des ReturnValue.

Es ist eine zusätzliche Funktion, bereitgestellt durch Python-obwohl für winzige Objekte, die __slots__ Attribut. Die Klasse könnte wie folgt ausgedrückt werden:

class ReturnValue(object):
  __slots__ = ["y0", "y1", "y2"]
  def __init__(self, y0, y1, y2):
     self.y0 = y0
     self.y1 = y1
     self.y2 = y2

Aus der Python-Referenz-Handbuch:

Den __slots__ Erklärung nimmt, eine Sequenz von Instanz-Variablen und behält sich nur genug Platz in jede Instanz einen Wert für jede variable. Speicherplatz wird gespart, weil __dict__ ist nicht geschaffen für jede Instanz.

Option: Mit einem dataclass (Python 3.7+)

Mit Python 3.7 neue dataclasses, zurückzukehren, eine Klasse, mit automatisch Hinzugefügt speziellen Methoden, schreib-und andere nützliche tools:

@dataclass
class Returnvalue:
    y0: int
    y1: float
    y3: int

def total_cost(x):
    y0 = x + 1
    y1 = x * 3
    y2 = y0 ** y3
    return ReturnValue(y0, y1, y2)

Option: Mit Hilfe einer Liste

Einen anderen Vorschlag, habe ich übersehen, kommt von Bill, die Eidechse:

def h(x):
  result = [x + 1]
  result.append(x * 3)
  result.append(y0 ** y3)
  return result

Dies ist mein wenigsten bevorzugten Methode wenn. Ich glaube, ich bin verdorben durch die Einwirkung von Haskell, aber die Idee des mixed-Typ-Listen hat immer das Gefühl unbequem zu mir. In diesem speziellen Beispiel die Liste ist -nicht - gemischter Typ, aber es denkbar sein könnte.

Einer Liste, die in dieser Art und Weise wirklich nicht alles gewinnen mit Bezug auf die Tupel, so weit ich erzählen kann. Der einzige wirkliche Unterschied zwischen Listen und Tupel in Python ist, dass Listen sind veränderlich, in der Erwägung, dass Tupel nicht.

Ich persönlich tendiere zu führen über die Konventionen aus der funktionalen Programmierung: die Verwendung von Listen für beliebige Anzahl von Elementen des gleichen Typs, und Tupeln wird eine Feste Anzahl von Elementen, die bestimmte Arten.

Frage

Nach der langen Präambel, kommt die unvermeidliche Frage. Welche Methode (denken Sie) am besten ist?

Ich habe in der Regel gefunden, werde mich selbst das Wörterbuch route, denn es handelt sich weniger set-up-Arbeit. Von einem Typen Perspektive allerdings könnten Sie besser dran, wenn man die Klasse route, da dies kann Ihnen helfen, zu vermeiden, verwirrend, was ein Wörterbuch repräsentiert.

Auf der anderen Seite gibt es auch einige in der Python-Gemeinschaft, die das Gefühl haben implizite Schnittstellen sollten bevorzugt werden, um explizite Schnittstellen, an welchem Punkt der Typ des Objekts ist nicht wirklich relevant, da Sie im wesentlichen unter Berufung auf die Konvention, dass das gleiche Attribut haben stets die gleiche Bedeutung.

So, wie Sie es tun-Sie - return mehrere Werte in Python?

  • In Ihnen hervorragende Beispiele, die Sie verwenden variable y3, aber es sei denn, y3 ist global deklariert, dies würde die Ausbeute NameError: global name 'y3' is not defined vielleicht verwenden Sie einfach 3?
InformationsquelleAutor saffsd | 2008-12-10
Schreibe einen Kommentar