วิธีที่เป็นที่ยอมรับในการส่งคืนค่าหลายค่าในภาษาที่สนับสนุนมักจะส่งเสียงซ้ำ
ตัวเลือก: การใช้ tuple
ลองพิจารณาตัวอย่างเล็ก ๆ น้อย ๆ นี้:
def f(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return (y0, y1, y2)
อย่างไรก็ตามสิ่งนี้จะได้รับปัญหาอย่างรวดเร็วเนื่องจากจำนวนของค่าที่ส่งคืนเพิ่มขึ้น ถ้าคุณต้องการคืนค่าสี่หรือห้าค่า แน่นอนว่าคุณสามารถติดตามพวกเขาได้ แต่มันก็ง่ายที่จะลืมคุณค่าที่เป็นอยู่ นอกจากนี้ยังค่อนข้างน่าเกลียดที่จะแกะกล่องพวกเขาทุกที่ที่คุณต้องการรับ
ตัวเลือก: การใช้พจนานุกรม
ขั้นตอนตรรกะถัดไปน่าจะเป็นการแนะนำ 'สัญกรณ์บันทึก' บางประเภท dict
ในหลามวิธีที่ชัดเจนที่จะทำเช่นนี้คือโดยวิธีการของ
พิจารณาสิ่งต่อไปนี้:
def g(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return {'y0': y0, 'y1': y1 ,'y2': y2}
(เพื่อให้ชัดเจน, y0, y1 และ y2 นั้นมีความหมายเป็นตัวบ่งชี้เชิงนามธรรมอย่างที่ทราบแล้วในทางปฏิบัติคุณจะต้องใช้ตัวระบุที่มีความหมาย)
ตอนนี้เรามีกลไกที่เราสามารถฉายสมาชิกเฉพาะของวัตถุที่ส่งคืน ตัวอย่างเช่น,
result['y0']
ตัวเลือก: การใช้คลาส
อย่างไรก็ตามมีตัวเลือกอื่น เราสามารถส่งคืนโครงสร้างพิเศษแทน ฉันใส่กรอบนี้ในบริบทของ Python แต่ฉันแน่ใจว่ามันใช้ได้กับภาษาอื่นเช่นกัน แน่นอนถ้าคุณทำงานใน C นี่อาจเป็นทางเลือกเดียวของคุณ ไปที่นี่:
class ReturnValue:
def __init__(self, y0, y1, y2):
self.y0 = y0
self.y1 = y1
self.y2 = y2
def g(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return ReturnValue(y0, y1, y2)
ในหลามก่อนหน้านี้สองอาจจะคล้ายกันมากในแง่ของการประปา - หลังจากทั้งหมด{ y0, y1, y2 }
เพียงแค่จบลงด้วยการรายการในภายในของ__dict__
ReturnValue
มีหนึ่งคุณสมบัติเพิ่มเติมที่จัดทำโดย Python แต่สำหรับวัตถุขนาดเล็ก__slots__
คุณลักษณะ ชั้นสามารถแสดงเป็น:
class ReturnValue(object):
__slots__ = ["y0", "y1", "y2"]
def __init__(self, y0, y1, y2):
self.y0 = y0
self.y1 = y1
self.y2 = y2
จากคู่มืออ้างอิง Python :
การ
__slots__
ประกาศใช้ลำดับของตัวแปรอินสแตนซ์และสำรองพื้นที่เพียงพอในแต่ละอินสแตนซ์เพื่อเก็บค่าสำหรับแต่ละตัวแปร ประหยัดพื้นที่เนื่องจาก__dict__
ไม่ได้สร้างสำหรับแต่ละอินสแตนซ์
ตัวเลือก: การใช้ดาต้าคลาส (Python 3.7+)
การใช้ดาต้าคลาสใหม่ของ Python 3.7 ให้ส่งคืนคลาสด้วยวิธีพิเศษการพิมพ์และเครื่องมือที่มีประโยชน์อื่น ๆ โดยอัตโนมัติ:
@dataclass
class Returnvalue:
y0: int
y1: float
y3: int
def total_cost(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return ReturnValue(y0, y1, y2)
ตัวเลือก: การใช้รายการ
ข้อเสนอแนะอีกข้อที่ฉันมองข้ามมาจาก Bill the Lizard:
def h(x):
result = [x + 1]
result.append(x * 3)
result.append(y0 ** y3)
return result
นี่เป็นวิธีที่ฉันชอบน้อยที่สุด ฉันคิดว่าฉันเสียเปรียบจากการสัมผัสกับ Haskell แต่ความคิดของรายการประเภทผสมมักจะรู้สึกไม่สบายสำหรับฉัน ในตัวอย่างนี้ลิสต์เป็นแบบไม่ผสม แต่อาจเป็นไปได้
รายการที่ใช้ในวิธีนี้จริง ๆ แล้วไม่ได้อะไรเลยเกี่ยวกับ tuple เท่าที่ฉันสามารถบอกได้ ความแตกต่างที่แท้จริงระหว่างรายการและสิ่งอันดับใน Python คือรายการนั้นไม่แน่นอนในขณะที่สิ่งอันดับจะไม่
ฉันมักจะดำเนินการตามอนุสัญญาจากการเขียนโปรแกรมการทำงาน: ใช้รายการสำหรับองค์ประกอบจำนวนใด ๆ ของประเภทเดียวกันและ tuples สำหรับองค์ประกอบจำนวนคงที่ของประเภทที่กำหนดไว้ล่วงหน้า
คำถาม
หลังจากการเริ่มนำที่มีความยาวมาเป็นคำถามที่หลีกเลี่ยงไม่ได้ วิธีใดที่คุณคิดว่าดีที่สุด?
y3
ที่จะทำงานเดียวกันได้เช่นกัน
y3
แต่ถ้าไม่มีการประกาศ y3 ทั่วโลกสิ่งนี้NameError: global name 'y3' is not defined
อาจให้ผลเพียงแค่ใช้3
?