ทำไมตัวสร้างไพ ธ อนและฟังก์ชั่นจึงใช้คำสั่ง“ def” ร่วมกัน?


10

พิจารณาสิ่งต่อไปนี้:

def some_function():
    return 1

def some_generator():
    yield 1

ในรหัสข้างต้นsome_functionเป็นฟังก์ชั่นในขณะที่some_generatorเป็นเครื่องกำเนิดไฟฟ้า พวกมันดูคล้ายกันมาก

ปัญหาที่ฉันมีเมื่ออ่านโค้ดคือฉันต้องสแกนผ่านทุกบรรทัดใน "ฟังก์ชั่น" เพื่อค้นหาyieldคำหลักก่อนที่ฉันจะสามารถตรวจสอบได้ว่ามันเป็นฟังก์ชั่นหรือเครื่องกำเนิดไฟฟ้าจริง ๆ !

สำหรับฉันดูเหมือนว่าการใช้คำหลักที่แตกต่างกันสำหรับเครื่องกำเนิดไฟฟ้าจะทำให้เข้าใจได้ง่ายขึ้นเช่น:

gen some_generator():
    yield 1

อะไรคือข้อดีของการใช้defคำหลักสำหรับเครื่องกำเนิดไฟฟ้าและฟังก์ชั่น? ทำไมคำหลักใหม่ไม่ได้ถูกนำมาใช้กับฟังก์ชั่นและเครื่องกำเนิดไฟฟ้าแยกกัน?


ฉันไม่ทราบคำตอบที่แท้จริง แต่ฉันมักจะเริ่มเขียนฟังก์ชั่นที่ส่งคืนรายการแล้วแปลงเป็นเครื่องกำเนิดไฟฟ้าเมื่อมันถูกต้อง การมีการจับคู่ไวยากรณ์ทำให้สิ่งนี้เป็นธรรมชาติยิ่งขึ้น
Gort the Robot

2
@StevenBurnap คำแนะนำของ Derek เกี่ยวกับการใช้สิ่งที่ต้องการgenแทนdefจะไม่ทำให้การเปลี่ยนแปลงนั้นยุ่งยากยิ่งขึ้น
jamesdlin

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

@jamesdlin: แต่คำถามคือการพิสูจน์ว่าคำหลักใหม่จะเป็นสิ่งที่จำเป็น
Giorgio

1
@jamesdlin: แน่นอนคุณสามารถแยกแยะฟังก์ชั่นและเครื่องกำเนิดไฟฟ้าได้โดยดูที่เนื้อหา แต่คำถามระบุว่าการใช้คำหลักต่าง ๆ จะทำให้โค้ดอ่านง่ายขึ้น
Giorgio

คำตอบ:


14

"ข้อดีของการใช้คำหลัก def สำหรับทั้งเครื่องกำเนิดและฟังก์ชันคืออะไร"

ในขณะที่พวกเขามีกลไกที่แตกต่างกันในทางปฏิบัติเมื่อฉันใช้พวกเขาพวกเขามักจะมีประสิทธิภาพเหมือนกันกับฉันแนวคิด (ฉันไม่คิดว่าการโทรrange()VS xrange())

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

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

ฉันไม่รู้สึกว่าการโต้แย้งของฉันมีความน่าเชื่อถือเป็นพิเศษแม้ว่าฉันจะเลื่อนไปที่PEP 255 :

ปัญหา: แนะนำคำหลักใหม่อีกคำ (พูด "gen" หรือ "ตัวสร้าง") แทนที่ "def" หรือเปลี่ยนแปลงไวยากรณ์เพื่อแยกความแตกต่างระหว่างตัวสร้างกับฟังก์ชันที่ไม่ใช่ตัวกำเนิด

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

Pro: ในความเป็นจริง (คุณคิดอย่างไรเกี่ยวกับพวกเขา), ฟังก์ชั่นเครื่องกำเนิดไฟฟ้าเป็นฟังก์ชั่นโรงงานที่ผลิตเครื่องกำเนิดไฟฟ้าซ้ำโดยเสมือน ในแง่นี้มันแตกต่างอย่างสิ้นเชิงจากฟังก์ชั่นที่ไม่ใช่เครื่องกำเนิดไฟฟ้าซึ่งทำหน้าที่เหมือนนวกรรมิกมากกว่าฟังก์ชั่นดังนั้นการนำ "def" กลับมาใช้ใหม่จะทำให้เกิดความสับสนมากที่สุด คำสั่ง "ผลผลิต" ที่ฝังอยู่ในร่างกายนั้นไม่เพียงพอที่จะเตือนว่าความหมายของคำนั้นแตกต่างกันมาก

BDFL: "def" มันยังคงอยู่ การถกเถียงกันทั้งสองด้านนั้นไม่น่าเชื่อเลยดังนั้นฉันจึงปรึกษาสัญชาตญาณของนักออกแบบภาษาของฉัน มันบอกฉันว่าไวยากรณ์ที่เสนอใน PEP นั้นถูกต้อง - ไม่ร้อนเกินไปหรือไม่เย็นเกินไป แต่เช่น Oracle ที่ Delphi ในเทพปกรณัมกรีกมันไม่ได้บอกฉันว่าทำไมดังนั้นฉันจึงไม่มีข้อโต้แย้งสำหรับการขัดแย้งกับไวยากรณ์ PEP สิ่งที่ดีที่สุดที่ฉันสามารถทำได้ (นอกเหนือจากการเห็นด้วยกับการโต้แย้ง ... ทำไปแล้ว) คือ "FUD" หากนี่เป็นส่วนหนึ่งของภาษาตั้งแต่วันแรกฉันสงสัยอย่างมากว่ามันจะทำให้หน้า "Python Warts" ของ Andrew Kuchling


1
มันเป็นที่น่าสังเกตว่าใหม่await(และ async withและasync for) โครงสร้างไวยากรณ์เพิ่มเข้ามาในPEP 492ซึ่งทำงานคล้ายกับyield fromต้องมีฟังก์ชั่นที่พวกเขากำลังที่ใช้ในการที่จะได้รับการประกาศใช้แทนที่จะเป็นเพียงแค่async def def
Feuermurmel

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

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


1

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

def some_function(): #This is a function.
    return 1

def some_generator(): #This is a generator.
    yield 1

0

ฉันเดาว่ามันเป็นเพราะมันเป็นไพทอนนิกมากกว่า แต่ฉันจะรู้อะไรได้บ้าง ;)

ฉันไม่คิดว่ามันจะสำคัญอะไรมากขนาดนั้น ง่ายต่อการจดจำสำหรับฉันเพราะไม่จำเป็นต้องจดจำทั้งคู่

แก้ไข: PEP อาจพูดว่าคุณสามารถตรวจสอบที่นั่น


ขอบคุณ! ในความเป็นจริง PEP จะพูด! ดูPEP-255สำหรับข้อดี / ข้อเสียและการตัดสินใจขั้นสุดท้ายเกี่ยวกับคำหลักใหม่สำหรับเครื่องกำเนิดไฟฟ้า
Derek Kwok

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