วัตถุประสงค์ของตัวแปรขีดล่าง“ _” ใน Python คืออะไร?


618

อะไรคือความหมายของ_after forในรหัสนี้?

if tbh.bag:
   n = 0
   for _ in tbh.bag.atom_set():
      n += 1


5
สำหรับกรณีของคุณมันจะสะอาดกว่าlen(tbh.bag.atom_set())หาก (ค่าที่ส่งคืนมี__len__วิธีการ) หรือsum(1 for _ in tbh.bag.atom_set())
Nick T

ในpylintอีกทางเลือกหนึ่งสำหรับชื่อตัวแปรจำลองคือคำนำหน้าของdummy_ชื่อตัวแปร การใช้ส่วนนำหน้านี้ด้วยpylintทำให้pylintไม่ส่งคำเตือน นอกจากนี้คุณสามารถกำหนดค่ารูปแบบตัวแปรดัมมี่สำหรับที่จะรองรับสิ่งที่ต้องการpylint __
Trevor Boyd Smith

คำตอบ:


780

_ มีการใช้งานทั่วไป 4 แบบใน Python:

  1. เพื่อเก็บผลลัพธ์ของนิพจน์ที่ดำเนินการล่าสุด (/ คำสั่ง) ในเซสชันล่ามแบบโต้ตอบ แบบอย่างนี้ถูกกำหนดโดยล่าม CPython มาตรฐานและล่ามอื่น ๆ ได้ปฏิบัติตามเหมาะสม
  2. สำหรับการค้นหาการแปลใน i18n (ดู ตัวอย่างเอกสารประกอบของgettext ) ดังเช่นในรหัสเช่น: raise forms.ValidationError(_("Please enter a correct username"))
  3. ในฐานะที่เป็นอเนกประสงค์ "ใบปลิว" ชื่อตัวแปรเพื่อแสดงให้เห็นส่วนหนึ่งของผลการทำงานที่ถูกละเลยจงใจ (แนวคิดก็จะถูกทิ้ง.) label, has_label, _ = text.partition(':')ในรหัสที่ชอบ:
  4. เป็นส่วนหนึ่งของการกำหนดฟังก์ชั่น (ใช้อย่างใดอย่างหนึ่งdefหรือlambda) ซึ่งลายเซ็นได้รับการแก้ไข (เช่นโดยการเรียกกลับหรือ API ระดับผู้ปกครอง) แต่การใช้งานฟังก์ชั่นนี้โดยเฉพาะไม่ต้องการพารามิเตอร์ทั้งหมดตามรหัสเช่น:callback = lambda _: True

(เป็นเวลานานคำตอบนี้จะแสดงเฉพาะสามกรณีการใช้งานครั้งแรก แต่กรณีที่สี่มาบ่อยพอดังที่ระบุไว้ที่นี่เพื่อเป็นรายการมูลค่าอย่างชัดเจน)

"ตัวแปร throwaway หรือชื่อพารามิเตอร์" หลังการใช้กรณีสามารถขัดแย้งกับกรณีการใช้การค้นหาการแปลดังนั้นจึงจำเป็นต้องหลีกเลี่ยงการใช้_เป็นตัวแปร throwaway ในบล็อกรหัสใด ๆ ที่ยังใช้มันสำหรับการแปล i18n (คนจำนวนมากต้องการคู่ขีดเส้นใต้ , __เป็นตัวแปรใบปลิวของพวกเขาสำหรับว่าด้วยเหตุนี้)


19
คุณสามารถอธิบายวิธีการทำงานในสายงานตัวอย่างเช่น: เพิ่ม forms.ValidationError (_ ( "กรุณากรอกชื่อผู้ใช้ที่ถูกต้อง")) ฉันเคยเห็นสิ่งนี้ในรหัส Django และมันไม่ชัดเจนว่าเกิดอะไรขึ้น
John C

41
นั่นคือการใช้งาน 2 - โดยการประชุม_คือชื่อที่ใช้สำหรับฟังก์ชั่นที่ทำการค้นหาการแปลสตริงและการแปลเป็นภาษาท้องถิ่น ฉันค่อนข้างแน่ใจว่ามันเป็นgettextห้องสมุดC ที่สร้างอนุสัญญา
ncoghlan

43
FWIW ฉันได้เริ่มใช้__(ขีดเส้นใต้สองครั้ง) เป็นการส่วนตัวโดยใช้ตัวแปร throwaway วัตถุประสงค์ของฉันเพื่อหลีกเลี่ยงความขัดแย้งกับกรณีการใช้สองกรณีแรก
ncoghlan

14
การประชุมชุมชนที่เกิดขึ้นไม่ได้มีแนวโน้มที่จะมีแหล่งข้อมูลที่เชื่อถือได้ - เพียงแค่สังเกตจากการปฏิบัติที่ปรากฏขึ้นเมื่อเวลาผ่านไป FWIW ฉันเป็นหนึ่งในผู้เขียนร่วมของการอัพเดท PEP 8 เมื่อเร็ว ๆ นี้และคำตอบของฉันขึ้นอยู่กับ 3 วิธีที่ต่างกันที่ฉันเห็นว่า_ใช้เป็นชื่อตัวแปรตั้งแต่ฉันเริ่มใช้ Python อย่างมืออาชีพในปี 2002
ncoghlan

12
การประชุมเป็นส่วนใหญ่สำหรับ tuple unpacking: a, __, c = iterableบอกผู้อ่านทันทีว่าเรากำลังแกะ 3-tuple แต่ใช้ค่าแรกและค่าสุดท้ายเท่านั้น ถ้าเราเขียนแทนa, b, c = iterableผู้อ่าน (หรือ linter รหัสอัตโนมัติ) มีเหตุผลสามารถคาดหวังทั้งหมดของa, bและcเพื่อใช้ในภายหลัง (และถ้าพวกเขาไม่ได้ก็อาจจะเป็นสัญญาณของบางข้อผิดพลาด)
ncoghlan

207

มันเป็นเพียงชื่อตัวแปรและเป็นเรื่องธรรมดาในงูหลามเพื่อใช้_สำหรับตัวแปรที่ถูกทิ้ง มันเพิ่งระบุว่าตัวแปรลูปไม่ได้ใช้จริง


5
คุณหมายถึงว่ามันไม่ได้เป็นตัวแทนของมูลค่าที่ส่งคืนล่าสุด?
alwbtc

31
@ สตีฟเท่านั้นในเปลือก
Gabi Purcaru

4
คล้ายกับการใช้ _ ใน Prolog
Matthias

3
คล้ายกับการใช้ ~ ใน Matlab
PatriceG

โปรดทราบว่าในเปลือก cpython ถ้าคุณกำหนดไว้อย่างชัดเจน_มันจะหยุดเก็บค่าเอาต์พุตของนิพจน์ก่อนหน้าอย่างถาวร สิ่งนี้ดูเหมือนจะไม่สอดคล้องกันอย่างน่ากลัวและมาตรฐาน Python lang จำเป็นต้องจัดการเรื่องนี้ พวกเขาควรกำหนด_ให้เป็นชื่อทิ้งและหยุดไม่ให้ใช้เป็นตัวระบุที่แท้จริง
theferrit32

78

ขีดเส้นใต้_ถือเป็นตัวแปร" ฉันไม่สนใจ " หรือ " Throwaway " ใน Python

  • _ร้านค้าล่ามหลามค่าสุดท้ายที่จะแสดงออกตัวแปรพิเศษที่เรียกว่า

    >>> 10 
    10
    
    >>> _ 
    10
    
    >>> _ * 3 
    30
  • ขีดเส้นใต้_ยังใช้สำหรับการละเว้นค่าเฉพาะ หากคุณไม่ต้องการค่าที่เฉพาะเจาะจงหรือไม่ได้ใช้ค่าเพียงกำหนดค่าให้ขีดล่าง

    ละเว้นค่าเมื่อเปิดออก

    x, _, y = (1, 2, 3)
    
    >>> x
    1
    
    >>> y 
    3

    ละเว้นดัชนี

    for _ in range(10):     
        do_something()

2
_("Hello world!")มีการใช้งานที่สามซึ่งเป็นฟังก์ชั่นเป็นสากล
Jeff Younker

3
ที่ระดับตัวประมวลผลจริง ๆ แล้วมีความแตกต่างระหว่าง "for _ in range" และ "for x in range" และไม่ใช้ x หรือไม่? หรือมันเป็นเพียงการอ่านของมนุษย์?
iammax

1
@iammax การใช้disโมดูลที่ฉันพบว่าไม่มีความแตกต่างใน bytecode อย่างไรก็ตามประโยชน์ของการอ่านของมนุษย์นั้นชัดเจนอย่างไรก็ตาม
Alistair Carscadden

21

มี 5 กรณีสำหรับการใช้เครื่องหมายขีดล่างใน Python

  1. สำหรับการเก็บค่าของการแสดงออกครั้งสุดท้ายในล่าม

  2. สำหรับการละเว้นค่าเฉพาะ (เรียกว่า“ ฉันไม่สนใจ”)

  3. เพื่อให้ความหมายและฟังก์ชั่นพิเศษกับชื่อของ vartiables หรือฟังก์ชั่น

  4. เพื่อใช้เป็นฟังก์ชั่น 'สากล (i18n)' หรือ 'Localization (l10n)'

  5. เพื่อแยกตัวเลขของค่าตัวอักษรตัวเลข

นี่เป็นบทความที่ดีกับตัวอย่างโดยmingrammer


2
ในความเป็นจริงมันเป็นblog.pythonlibrary.org/2017/01/11/…
MichaelChirico

3

สำหรับภาษา Python นั้น_ไม่มีความหมายพิเศษ มันเป็นความถูกต้องระบุเช่นเดียว_foo, หรือfoo__f_o_o_

ความหมายพิเศษใด ๆ_ก็คือโดยการประชุมอย่างแท้จริง หลายกรณีเป็นเรื่องธรรมดา:

  • ชื่อดัมมี่เมื่อไม่ต้องการใช้ตัวแปร แต่ต้องการชื่อโดยไวยากรณ์ / ซีแมนทิกส์

    # iteration disregarding content
    sum(1 for _ in some_iterable)
    # unpacking disregarding specific elements
    head, *_ = values
    # function disregarding its argument
    def callback(_): return True
  • REPLs / shells จำนวนมากเก็บผลลัพธ์ของนิพจน์ระดับบนสุดbuiltins._ไว้

    ตัวระบุพิเศษ_ถูกใช้ในล่ามแบบโต้ตอบเพื่อเก็บผลลัพธ์ของการประเมินครั้งล่าสุด มันถูกเก็บไว้ในbuiltinsโมดูล เมื่อไม่ได้อยู่ในโหมดโต้ตอบ_ไม่มีความหมายพิเศษและไม่ได้กำหนด [ แหล่งที่มา ]

    เนื่องจากวิธีการชื่อเงยหน้าขึ้นมองเว้นแต่เงาโดยทั่วโลกหรือท้องถิ่น_นิยามเปลือยหมายถึง_builtins._

    >>> 42
    42
    >>> f'the last answer is {_}'
    'the last answer is 42'
    >>> _
    'the last answer is 42'
    >>> _ = 4  # shadow ``builtins._`` with global ``_``
    >>> 23
    23
    >>> _
    4

    หมายเหตุ:เปลือกหอยบางอย่างเช่นipythonไม่กำหนดให้แต่กรณีพิเศษbuiltins.__

  • ในบริบทสากลและการแปล_จะใช้เป็นนามแฝงสำหรับฟังก์ชั่นการแปลหลัก

    gettext.gettext (ข้อความ)

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

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