Tuple tanımlarında sonda virgül bulundurmanın sözdizimi kuralı nedir?


120

Tek bir öğe demeti olması durumunda, sondaki virgül gereklidir.

a = ('foo',)

Birden çok öğeye sahip bir demet ne olacak? Sondaki virgül var olsun ya da olmasın, her ikisi de geçerli görünüyor. Bu doğru mu? Sonunda virgül kullanmak bence düzenlemek için daha kolay. Bu kötü bir kodlama stili mi?

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

Sözdizimi kuralı şöyledir
Kirill

Yanıtlar:


73

Boş demet hariç tüm durumlarda virgül önemli olan şeydir. Parantezler yalnızca diğer sözdizimsel nedenler için gerekli olduğunda gereklidir: bir demeti bir işlev bağımsız değişkenleri kümesinden ayırmak, operatör önceliği veya satır kesmelerine izin vermek.

Tuple'lar, listeler veya işlev argümanları için sondaki virgül, özellikle birden çok satıra bölünmüş uzun bir başlatmanız olduğunda iyi bir stildir. Her zaman sonda virgül eklerseniz, sona başka bir öğe eklemeyi ve bunun yerine geçerli bir ifade oluşturmayı bekleyen başka bir satır eklemeyeceksiniz:

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

Daha sonra uzatılan 2 öğeli bir liste olarak başladığını varsayarsak, belki de hemen belli olmayan bir şekilde yanlış gitti. Her zaman sondaki virgül ekleyin ve bu tuzaktan kaçının.


3
Yukarıda belirtilen nedenlerden dolayı virgül bırakmak avantajlı olabilir. Öte yandan, bu alışkanlığı benimsemek, uygulamanızın başka bir yerinde JavaScript veya JSON ile de uğraşıyorsanız baş ağrısına yol açabilir, çünkü bazı tarayıcılar oradan hoşlanmaz.
Cito

7
Evet, ancak JSON'u hiçbir zaman elle oluşturmamalısınız ki bu önemli değil ve Javascript için her zaman jslint veya eşdeğerini kullanarak bu tür bir hatayı tarayıcıya yaklaşmadan önce yakalayın.
Duncan

101

Yalnızca tek öğeli demetler için, bir demeti veya parantezlerle çevrili bir ifadeyi tanımlarken belirsizliği gidermek gerekir.

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

Birden fazla öğe için, bunun bir demet olduğu tamamen açık olduğundan artık gerekli değildir. Bununla birlikte, sondaki virgülün birden çok satır kullanarak tanımlanmasını kolaylaştırmasına izin verilir. Sözdizimini bozmadan öğeleri sonuna ekleyebilir veya yeniden düzenleyebilirsiniz çünkü kaza durumunda virgül atlamışsınızdır.

Örneğin,

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

Bunun diğer koleksiyonlar (ör. Listeler ve sözlükler) için de geçerli olduğunu ve yalnızca demetler için geçerli olmadığını unutmayın.


5
+1, bunun tuple dışındaki diğer şeyler için de geçerli olduğuna işaret ettiği için. Bu, key: value,satır başına bir tane olması için çok faydalıdır ve yeni şeyler eklerken virgülle ilgilenmeyin.
Joël

46

Sondaki virgüllerin bir başka avantajı da farkların daha güzel görünmesini sağlamasıdır. İle başladıysan

a = [
    1,
    2,
    3
]

ve değiştirdi

a = [
    1,
    2,
    3,
    4
]

Fark şöyle görünürdü

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

Oysa son virgülle başlamış olsaydınız,

a = [
    1,
    2,
    3,
]

O zaman fark sadece

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

Bu gerçekten orijinal sorunun cevabından çok bir yorumdur, ancak sondaki virgüllerin lehine eklenen argümanı gerçekten seviyorum.
Mad Physicist


8

Ayrıca, istediğiniz durumu düşünün:

>>> (('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'))

Bu durumda, dış parantezler parantezleri gruplamaktan başka bir şey değildir. Onları tuple yapmak için sondaki virgül eklemeniz gerekir. yani

>>> (('x','y'),)*4 
(('x', 'y'), ('x', 'y'), ('x', 'y'), ('x', 'y'))

6

Sondaki virgül, yalnızca tek öğeli diziler için gereklidir. Daha büyük demetler için sonda virgül kullanmak bir stil meselesidir ve gerekli değildir. En büyük avantajı, genellikle değiştirilen çok satırlı büyük kayıtlara sahip dosyalardaki temiz farktır (örneğin, yapılandırma grupları).


6

Bu basit bir cevap.

a = ("s") bir dizedir

ve

a = ("s",) tek elemanlı bir demettir.

Python, bir eleman tuple olması durumunda, string ve tuple arasında ayrım yapmak için ek bir virgül gerektirir.

Örneğin bunu python konsolunda deneyin:

a = ("s")

a = a + (1,2,3)

Traceback (en son çağrı son):

Dosya stdin, satır 1, modülde

TypeError: 'str' ve 'tuple' nesneleri birleştirilemez


4

Bunun var olmasının bir başka nedeni de kod üretimini ve __repr__fonksiyonları yazmayı kolaylaştırmasıdır. Örneğin, benzer şekilde oluşturulmuş bir nesneniz varsa obj(arg1, arg2, ..., argn), o zaman şu şekilde yazabilirsiniz obj.__repr__:

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)

Sondaki virgüllere izin verilmediyse, son argümanı özel olarak yazmanız gerekir. Aslında, yukarıdakileri bir liste anlayışı kullanarak tek satırda yazabilirsiniz (okumayı kolaylaştırmak için daha uzun yazdım). Son dönem için özel bir durum olsaydı, bunu yapmak o kadar kolay olmazdı.


2
Son argüman, tek sadece kullanabilirsiniz özel durum gerek yoktur olacağını joinbu durumda: def __repr__(self): 'obj(' + ', '.join([repr(arg) for arg in obj.args]) + ')'.
Suzanne Dupéron

Ayrıca Python'da yazılmamış ve join.
asmeurer

2

PEP 8 - Python Kodu için Stil Kılavuzu - Sondaki Virgül Ne Zaman Kullanılmalı

Sondaki virgüller genellikle isteğe bağlıdır, ancak bir öğeden oluşan bir demet oluştururken zorunludurlar (ve Python 2'de print deyimi için anlamsaldırlar). Netlik sağlamak için, ikincisini (teknik olarak gereksiz) parantez içine almanız önerilir.

Evet:

FILES = ('setup.cfg',)

Tamam, ama kafa karıştırıcı:

FILES = 'setup.cfg',

Sondaki virgüller gereksiz olduğunda, bir sürüm kontrol sistemi kullanıldığında, değerler listesinin, bağımsız değişkenlerin veya içe aktarılan öğelerin zamanla genişletilmesi beklendiğinde genellikle yararlıdırlar. Desen, her bir değeri (vb.) Kendi başına bir satıra koymak, her zaman sondaki virgül eklemek ve sonraki satıra yakın parantez / parantez / parantez eklemektir. Bununla birlikte, kapanış sınırlayıcısı ile aynı satırda sonda virgül bulunması mantıklı değildir (yukarıdaki tekil demetler hariç).

Evet:

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

Hayır:

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

-5

Kodlama stili sizin zevkinizdir, Standart kodlamanın önemli olduğunu düşünüyorsanız size rehberlik edebilecek bir PEP-8 vardır .

Aşağıdaki ifadenin sonucu hakkında ne düşünüyorsunuz?

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

Evet, x sadece bir sayı.


1
bu, düşünce tarzınızı açıklamanın kötü bir yolu. Açık, örtük olmaktan daha iyidir.
Guilherme David da Costa
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.