กฎไวยากรณ์สำหรับการมีเครื่องหมายจุลภาคต่อท้ายในคำจำกัดความทูเพิลคืออะไร?


121

ในกรณีของทูเปิลองค์ประกอบเดียวจำเป็นต้องใช้เครื่องหมายจุลภาคต่อท้าย

a = ('foo',)

สิ่งที่เกี่ยวกับทูเปิลที่มีหลายองค์ประกอบ? ดูเหมือนว่าไม่ว่าจะมีเครื่องหมายจุลภาคต่อท้ายหรือไม่ทั้งคู่ก็ใช้ได้ ถูกต้องหรือไม่ การมีเครื่องหมายจุลภาคต่อท้ายนั้นง่ายกว่าสำหรับการแก้ไขในความคิดของฉัน เป็นรูปแบบการเข้ารหัสที่ไม่ดีหรือไม่?

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

นี่คือกฎไวยากรณ์: docs.python.org/reference/expressions.html#expression-lists
Kirill

คำตอบ:


73

ในทุกกรณียกเว้นทูเพิลว่างเครื่องหมายจุลภาคคือสิ่งสำคัญ วงเล็บจะต้องใช้เฉพาะเมื่อจำเป็นสำหรับเหตุผลทางวากยสัมพันธ์อื่น ๆ : เพื่อแยกความแตกต่างของทูเปิลจากชุดของอาร์กิวเมนต์ของฟังก์ชันลำดับความสำคัญของตัวดำเนินการหรือเพื่อให้ตัวแบ่งบรรทัด

เครื่องหมายจุลภาคต่อท้ายสำหรับ tuples รายการหรืออาร์กิวเมนต์ของฟังก์ชันเป็นรูปแบบที่ดีโดยเฉพาะอย่างยิ่งเมื่อคุณมีการเริ่มต้นที่ยาวซึ่งแบ่งออกเป็นหลายบรรทัด หากคุณใส่เครื่องหมายจุลภาคต่อท้ายเสมอคุณจะไม่เพิ่มบรรทัดอื่นต่อท้ายโดยคาดหวังว่าจะเพิ่มองค์ประกอบอื่นและสร้างนิพจน์ที่ถูกต้องแทน:

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

สมมติว่าเริ่มต้นเป็นรายการองค์ประกอบ 2 รายการที่ขยายในภายหลังมันผิดพลาดในทางที่ไม่ชัดเจนในทันที ใส่เครื่องหมายจุลภาคต่อท้ายเสมอและหลีกเลี่ยงกับดักนั้น


4
ด้วยเหตุผลที่ระบุไว้ข้างต้นการออกจากเครื่องหมายจุลภาคจะเป็นประโยชน์ ในทางกลับกันการใช้นิสัยนี้อาจทำให้ปวดหัวได้หากคุณจัดการกับ JavaScript หรือ JSON ที่อื่นในแอปพลิเคชันของคุณเนื่องจากเบราว์เซอร์บางตัวไม่ชอบที่นั่น
Cito

7
ใช่ แต่คุณไม่ควรสร้าง JSON ด้วยมือเพื่อไม่ให้เป็นเรื่องสำคัญและสำหรับ Javascript มักใช้ jslint หรือเทียบเท่าเพื่อตรวจจับข้อผิดพลาดประเภทนั้นก่อนที่จะเข้าใกล้เบราว์เซอร์
Duncan

101

จำเป็นสำหรับสิ่งที่เป็นรายการเดียวเท่านั้นที่จะทำให้การกำหนดทูเพิลหรือนิพจน์ที่ล้อมรอบด้วยวงเล็บ

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

สำหรับรายการมากกว่าหนึ่งรายการไม่จำเป็นอีกต่อไปเนื่องจากชัดเจนว่าเป็นทูเพิล อย่างไรก็ตามอนุญาตให้ใช้เครื่องหมายจุลภาคต่อท้ายเพื่อกำหนดโดยใช้หลายบรรทัดได้ง่ายขึ้น คุณสามารถเพิ่มในตอนท้ายหรือจัดเรียงรายการใหม่โดยไม่ทำลายไวยากรณ์เนื่องจากคุณทิ้งลูกน้ำไว้โดยไม่ได้ตั้งใจ

เช่น,

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

โปรดทราบว่าสิ่งนี้ใช้ได้กับคอลเล็กชันอื่น ๆ (เช่นรายการและพจนานุกรม) ด้วยไม่ใช่แค่สิ่งที่เพิ่มขึ้น


5
+1 เพื่อชี้ให้เห็นว่าสิ่งนี้ใช้ได้กับสิ่งอื่นที่ไม่ใช่สิ่งที่เพิ่มขึ้น สิ่งนี้มีประโยชน์มากสำหรับการมีหนึ่งรายการkey: value,ต่อบรรทัดและไม่ต้องดูแลลูกน้ำเมื่อเพิ่มสิ่งใหม่ ๆ
Joël

46

ข้อดีอีกอย่างของเครื่องหมายจุลภาคต่อท้ายคือทำให้ความแตกต่างดูดีขึ้น หากคุณเริ่มต้นด้วย

a = [
    1,
    2,
    3
]

และเปลี่ยนเป็น

a = [
    1,
    2,
    3,
    4
]

ความแตกต่างจะมีลักษณะดังนี้

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

ในขณะที่คุณเริ่มต้นด้วยเครื่องหมายจุลภาคต่อท้ายเช่น

a = [
    1,
    2,
    3,
]

จากนั้นความแตกต่างก็จะเป็น

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

นี่เป็นความคิดเห็นมากกว่าคำตอบสำหรับคำถามเดิม แต่ฉันชอบอาร์กิวเมนต์ที่เพิ่มเข้ามาโดยใช้เครื่องหมายจุลภาคต่อท้าย
Mad Physicist

13

มันเป็นตัวเลือก: ดูวิกิพีเดียหลาม

สรุป: สิ่งที่เป็นองค์ประกอบเดียวต้องมีเครื่องหมายจุลภาคต่อท้ายแต่เป็นทางเลือกสำหรับสิ่งที่เพิ่มขึ้นหลายองค์ประกอบ


7

นอกจากนี้ให้พิจารณาสถานการณ์ที่คุณต้องการ:

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

ดังนั้นในกรณีนี้วงเล็บด้านนอกจึงไม่มีอะไรมากไปกว่าการจัดกลุ่มวงเล็บ ในการทำให้เป็นทูเพิลคุณต้องเพิ่มเครื่องหมายจุลภาคต่อท้าย กล่าวคือ

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

อย่าคิดว่าคำตอบนี้เกี่ยวข้องคำถามมากกว่าการใช้ผิดวัตถุประสงค์ของtuple หากเราคาดว่าองค์ประกอบที่ซ้ำกันเป็นประเภททูเปิลเราจะประกาศประเภทของหน่วยนี้เป็นทูเพิลองค์ประกอบเดียวอย่างชัดเจน เช่นเดียวกับกับรายการ , ลอง['x', 'y'] * 4, [ ['x', 'y'] ] * 4, ( ['x', 'y'], ) * 4
Kuo

6

ต้องมีเครื่องหมายจุลภาคต่อท้ายสำหรับทูเพิลหนึ่งองค์ประกอบเท่านั้น การมีเครื่องหมายจุลภาคต่อท้ายสำหรับสิ่งที่มีขนาดใหญ่ขึ้นเป็นเรื่องของรูปแบบและไม่จำเป็นต้องใช้ ข้อได้เปรียบที่ยิ่งใหญ่ที่สุดของมันคือความแตกต่างที่ชัดเจนในไฟล์ที่มีสิ่งต่อพ่วงขนาดใหญ่หลายบรรทัดซึ่งมักจะถูกแก้ไข


6

นั่นเป็นคำตอบง่ายๆ

a = ("s") คือสตริง

และ

a = ("s",) คือทูเพิลที่มีองค์ประกอบเดียว

Python ต้องการเครื่องหมายจุลภาคเพิ่มเติมในกรณีที่มีองค์ประกอบหนึ่งทูเพิลเพื่อแยกความแตกต่างระหว่างสตริงและทูเปิล

ตัวอย่างเช่นลองสิ่งนี้บนคอนโซล python:

a = ("s")

a = a + (1,2,3)

Traceback (โทรล่าสุดล่าสุด):

ไฟล์ stdin บรรทัด 1 ในโมดูล

TypeError: ไม่สามารถเชื่อมต่อวัตถุ 'str' และ 'tuple' ได้


4

อีกเหตุผลหนึ่งที่มีอยู่ก็คือทำให้การสร้างโค้ดและ__repr__ฟังก์ชันง่ายขึ้นในการเขียน ตัวอย่างเช่นหากคุณมีวัตถุบางอย่างที่สร้างขึ้นobj(arg1, arg2, ..., argn)คุณสามารถเขียน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)

หากไม่อนุญาตให้ใช้เครื่องหมายจุลภาคต่อท้ายคุณจะต้องใช้อาร์กิวเมนต์สุดท้ายเป็นกรณีพิเศษ ในความเป็นจริงคุณสามารถเขียนข้างต้นในบรรทัดเดียวโดยใช้ความเข้าใจในรายการ (ฉันเขียนไว้ยาวกว่านี้เพื่อให้อ่านง่ายขึ้น) มันคงไม่ใช่เรื่องง่ายที่จะทำเช่นนั้นหากคุณต้องเป็นกรณีพิเศษในเทอมสุดท้าย


2
ก็จะต้องไม่มีกรณีพิเศษอาร์กิวเมนต์สุดท้ายหนึ่งก็สามารถใช้ในกรณีที่ว่า:join def __repr__(self): 'obj(' + ', '.join([repr(arg) for arg in obj.args]) + ')'
Suzanne Dupéron

นอกจากนี้ยังช่วยในการสร้างโค้ดแม้จากเครื่องมือที่ไม่ได้เขียนด้วย Python และไม่มีฟังก์ชันที่ดีเช่นjoin.
asmeurer

3

PEP 8 - คำแนะนำสไตล์สำหรับรหัส Python - เมื่อใดควรใช้เครื่องหมายจุลภาคต่อท้าย

โดยทั่วไปแล้วเครื่องหมายจุลภาคต่อท้ายจะเป็นทางเลือกยกเว้นว่าจำเป็นเมื่อสร้างทูเพิลขององค์ประกอบเดียว (และใน Python 2 จะมีความหมายสำหรับคำสั่งพิมพ์) เพื่อความชัดเจนขอแนะนำให้ล้อมหลังไว้ในวงเล็บ (ซ้ำซ้อนทางเทคนิค)

ใช่:

FILES = ('setup.cfg',)

ตกลง แต่สับสน:

FILES = 'setup.cfg',

เมื่อเครื่องหมายจุลภาคต่อท้ายซ้ำซ้อนมักจะมีประโยชน์เมื่อใช้ระบบควบคุมเวอร์ชันเมื่อรายการของค่าอาร์กิวเมนต์หรือรายการที่นำเข้าคาดว่าจะขยายออกไปเมื่อเวลาผ่านไป รูปแบบคือการใส่แต่ละค่า (ฯลฯ ) ลงในบรรทัดด้วยตัวเองโดยเพิ่มเครื่องหมายจุลภาคต่อท้ายเสมอและเพิ่มวงเล็บปิด / วงเล็บ / วงเล็บปีกกาในบรรทัดถัดไป อย่างไรก็ตามมันไม่สมเหตุสมผลที่จะมีเครื่องหมายจุลภาคต่อท้ายในบรรทัดเดียวกับตัวคั่นปิด (ยกเว้นในกรณีด้านบนของสิ่งต่อไปนี้ของ singleton)

ใช่:

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

No:

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

-5

สไตล์การเข้ารหัสคือรสนิยมของคุณหากคุณคิดว่ามาตรฐานการเข้ารหัสมีความสำคัญมีPEP-8ที่สามารถแนะนำคุณได้

คุณคิดอย่างไรกับผลลัพธ์ของการแสดงออกต่อไปนี้?

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

ใช่ x เป็นเพียงตัวเลข


1
นั่นเป็นวิธีที่ไม่ดีในการอธิบายแนวความคิดของคุณ Explicit ดีกว่าโดยปริยาย
Guilherme David da Costa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.