Was ist die Syntaxregel für nachgestellte Kommas in Tupeldefinitionen?

118

Bei einem einzelnen Elementtupel ist das nachfolgende Komma erforderlich.

a = ('foo',)

Was ist mit einem Tupel mit mehreren Elementen? Unabhängig davon, ob das nachfolgende Komma vorhanden ist oder nicht, sind beide gültig. Ist das richtig? Ein nachfolgendes Komma zu haben ist meiner Meinung nach einfacher zu bearbeiten. Ist das ein schlechter Codierungsstil?

a = ('foo1', 'foo2')
b = ('foo1', 'foo2',)
Stan
quelle

Antworten:

73

In allen Fällen außer dem leeren Tupel ist das Komma das Wichtigste. Klammern sind nur erforderlich, wenn sie aus anderen syntaktischen Gründen erforderlich sind: um ein Tupel von einer Reihe von Funktionsargumenten zu unterscheiden, Operator-Priorität zu haben oder Zeilenumbrüche zuzulassen.

Das nachfolgende Komma für Tupel, Listen oder Funktionsargumente ist ein guter Stil, insbesondere wenn Sie eine lange Initialisierung haben, die über mehrere Zeilen verteilt ist. Wenn Sie immer ein nachfolgendes Komma einfügen, fügen Sie am Ende keine weitere Zeile hinzu, da Sie ein weiteres Element hinzufügen und stattdessen nur einen gültigen Ausdruck erstellen:

a = [
   "a",
   "b"
   "c"
]

Angenommen, dies begann als 2-Elemente-Liste, die später erweitert wurde, ist auf möglicherweise nicht sofort offensichtliche Weise ein Fehler aufgetreten. Fügen Sie immer das nachfolgende Komma ein, und Sie vermeiden diese Falle.

Duncan
quelle
3
Aus den oben genannten Gründen kann das Belassen des Kommas vorteilhaft sein. Andererseits kann die Übernahme dieser Gewohnheit zu Kopfschmerzen führen, wenn Sie sich auch an anderer Stelle in Ihrer Anwendung mit JavaScript oder JSON beschäftigen, da es einigen Browsern dort nicht gefällt.
Cito
7
Ja, aber Sie sollten JSON niemals von Hand erstellen, damit dies keine Rolle spielt. Verwenden Sie für Javascript immer jslint oder ein gleichwertiges Element, um diese Art von Fehler abzufangen, bevor er sich einem Browser nähert.
Duncan
100

Es ist nur erforderlich, dass Tupel mit einem Element die Definition eines Tupels oder eines Ausdrucks in Klammern eindeutig definieren.

(1)  # the number 1 (the parentheses are wrapping the expression `1`)
(1,) # a 1-tuple holding a number 1

Für mehr als einen Artikel ist dies nicht mehr erforderlich, da klar ist, dass es sich um ein Tupel handelt. Das nachfolgende Komma erleichtert jedoch die Definition in mehreren Zeilen. Sie können Elemente am Ende hinzufügen oder neu anordnen, ohne die Syntax zu beschädigen, da Sie bei einem Unfall ein Komma weggelassen haben.

z.B,

someBigTuple = (
                   0,
                   1,
                   2,
                   3,
                   4,
                   5,
                   6,
                   7,
                   8,
                   9,
                   10,
                   #...
                   10000000000,
               )

Beachten Sie, dass dies auch für andere Sammlungen (z. B. Listen und Wörterbücher) gilt und nicht nur für Tupel.

Jeff Mercado
quelle
5
+1 für den Hinweis, dass dies auch für andere Dinge als Tupel gilt. Dies ist sooo nützlich, um eine key: value,pro Zeile zu haben, und achten Sie beim Hinzufügen neuer Inhalte nicht auf Kommas.
Joël
46

Ein weiterer Vorteil von nachgestellten Kommas besteht darin, dass Unterschiede besser aussehen. Wenn Sie mit angefangen haben

a = [
    1,
    2,
    3
]

und änderte es zu

a = [
    1,
    2,
    3,
    4
]

Der Diff würde so aussehen

 a = [
     1,
     2,
-    3
+    3,
+    4
 ]

Wenn Sie mit einem nachgestellten Komma begonnen hätten, wie z

a = [
    1,
    2,
    3,
]

Dann wäre der Unterschied einfach

 a = [
     1,
     2,
     3,
+    4,
 ]
asmeurer
quelle
Dies ist eigentlich eher ein Kommentar als eine Antwort auf die ursprüngliche Frage, aber ich mag das hinzugefügte Argument für nachgestellte Kommas sehr.
Mad Physicist
13

Es ist optional: siehe Python-Wiki .

Zusammenfassung: Einzelelement-Tupel benötigen ein nachfolgendes Komma , sind jedoch für Mehrelement-Tupel optional .

Dave Everitt
quelle
8

Berücksichtigen Sie auch die Situation, in der Sie möchten:

>>> (('x','y'))*4                         # same as ('x','y')*4
('x', 'y', 'x', 'y', 'x', 'y', 'x', 'y')
#Expected = (('x', 'y'), ('x', 'y'), ('x', 'y'), ('x', 'y'))

In diesem Fall sind die äußeren Klammern nichts anderes als das Gruppieren von Klammern. Um sie zu tupeln, müssen Sie ein nachfolgendes Komma hinzufügen. dh

>>> (('x','y'),)*4 
(('x', 'y'), ('x', 'y'), ('x', 'y'), ('x', 'y'))
MaPy
quelle
6

Nachfolgendes Komma ist nur für Tupel mit einem Element erforderlich. Ein nachkommendes Komma für größere Tupel ist eine Frage des Stils und nicht erforderlich. Der größte Vorteil ist der saubere Unterschied bei Dateien mit mehrzeiligen großen Tupeln, die häufig geändert werden (z. B. Konfigurationstupel).

Adam Zalcman
quelle
6

Das ist eine einfache Antwort.

a = ("s") ist eine Zeichenfolge

und

a = ("s",) ist ein Tupel mit einem Element.

Python benötigt ein zusätzliches Komma, wenn ein Element Tupel enthält, um zwischen String und Tupel zu unterscheiden.

Versuchen Sie dies beispielsweise auf der Python-Konsole:

a = ("s")

a = a + (1,2,3)

Traceback (letzter Anruf zuletzt):

Datei stdin, Zeile 1, im Modul

TypeError: Objekte 'str' und 'tuple' können nicht verkettet werden

Rajni Kant
quelle
4

Ein weiterer Grund dafür ist, dass die Codegenerierung und die __repr__Funktionen einfacher zu schreiben sind. Wenn Sie beispielsweise ein Objekt haben, das so aufgebaut ist obj(arg1, arg2, ..., argn), können Sie einfach obj.__repr__als schreiben

def __repr__(self):
    l = ['obj(']
    for arg in obj.args: # Suppose obj.args == (arg1, arg2, ..., argn)
        l.append(repr(arg))
        l.append(', ')
    l.append(')')
    return ''.join(l)

Wenn ein nachfolgendes Komma nicht erlaubt wäre, müssten Sie das letzte Argument als Sonderfall angeben. Tatsächlich könnten Sie das Obige mit einem Listenverständnis in eine Zeile schreiben (ich habe es länger geschrieben, um das Lesen zu erleichtern). Das wäre nicht so einfach, wenn Sie in der letzten Amtszeit einen Sonderfall hätten.

asmeurer
quelle
2
Es wäre nicht nötig, das letzte Argument als Sonderfall zu verwenden, man könnte es nur joinin diesem Fall verwenden : def __repr__(self): 'obj(' + ', '.join([repr(arg) for arg in obj.args]) + ')'.
Suzanne Dupéron
Es hilft auch bei der Codegenerierung, selbst mit Tools, die nicht in Python geschrieben sind und keine netten Funktionen haben join.
Asmeurer
2

PEP 8 - Style Guide für Python-Code - Verwendung von nachgestellten Kommas

Nachgestellte Kommas sind normalerweise optional, außer sie sind obligatorisch, wenn ein Tupel aus einem Element erstellt wird (und in Python 2 haben sie eine Semantik für die print-Anweisung). Aus Gründen der Übersichtlichkeit wird empfohlen, letztere in (technisch redundante) Klammern zu setzen.

Ja:

FILES = ('setup.cfg',)

OK, aber verwirrend:

FILES = 'setup.cfg',

Wenn nachfolgende Kommas redundant sind, sind sie häufig hilfreich, wenn ein Versionskontrollsystem verwendet wird und wenn erwartet wird, dass eine Liste von Werten, Argumenten oder importierten Elementen im Laufe der Zeit erweitert wird. Das Muster besteht darin, jeden Wert (usw.) für sich in eine Zeile zu setzen, wobei immer ein nachfolgendes Komma hinzugefügt wird, und in der nächsten Zeile die enge Klammer / Klammer / Klammer hinzuzufügen. Es ist jedoch nicht sinnvoll, ein abschließendes Komma in derselben Zeile wie das schließende Trennzeichen zu haben (außer im obigen Fall von Singleton-Tupeln).

Ja:

FILES = [
    'setup.cfg',
    'tox.ini',
    ]
initialize(FILES,
           error=True,
           )

Nein:

FILES = ['setup.cfg', 'tox.ini',]
initialize(FILES, error=True,)
Schnelles Spiel
quelle
-5

Der Codierungsstil ist Ihr Geschmack. Wenn Sie der Meinung sind, dass der Codierungsstandard wichtig ist, gibt es einen PEP-8 , der Sie leiten kann.

Was halten Sie vom Ergebnis des folgenden Ausdrucks?

x = (3)
x = (3+2)
x = 2*(3+2)

Ja, x ist nur eine Zahl.

Melug
quelle
1
Das ist eine schlechte Art, Ihren Gedankengang zu erklären. Explizit ist besser als implizit.
Guilherme David da Costa