ฉันเจอสิ่งนี้ในโครงการโอเพ่นซอร์ส เมธอดที่แก้ไขแอ็ตทริบิวต์อินสแตนซ์ส่งคืนการอ้างอิงไปยังอินสแตนซ์ จุดประสงค์ของการสร้างนี้คืออะไร?
class Foo(object):
def __init__(self):
self.myattr = 0
def bar(self):
self.myattr += 1
return self
ฉันเจอสิ่งนี้ในโครงการโอเพ่นซอร์ส เมธอดที่แก้ไขแอ็ตทริบิวต์อินสแตนซ์ส่งคืนการอ้างอิงไปยังอินสแตนซ์ จุดประสงค์ของการสร้างนี้คืออะไร?
class Foo(object):
def __init__(self):
self.myattr = 0
def bar(self):
self.myattr += 1
return self
คำตอบ:
มันเป็นการยอมให้ผูกมัด
ตัวอย่างเช่น:
var Car = function () {
return {
gas : 0,
miles : 0,
drive : function (d) {
this.miles += d;
this.gas -= d;
return this;
},
fill : function (g) {
this.gas += g;
return this;
},
};
}
ตอนนี้คุณสามารถพูดได้:
var c = Car();
c.fill(100).drive(50);
c.miles => 50;
c.gas => 50;
ในฐานะที่เป็น @Lie Ryan และ @Frank Shearar พูดถึงสิ่งนี้เรียกว่า "ส่วนต่อประสานที่คล่องแคล่ว" แต่รูปแบบดังกล่าวนั้นใช้เวลานานมาก
ส่วนที่ถกเถียงกันของรูปแบบนั้นก็คือใน OO คุณมีสถานะที่ไม่แน่นอนดังนั้นวิธีที่เป็นโมฆะจึงมีค่าตอบแทนโดยนัยเท่ากับthis
- นั่นคือวัตถุที่มีสถานะที่อัปเดตนั้นเป็นค่าตอบแทน
ดังนั้นในภาษา OO ที่มีสถานะไม่แน่นอนทั้งสองนี้จะเทียบเท่ากันมากหรือน้อย:
a.doA()
a.doB()
a.doC()
...ตรงข้ามกับ
a.doA().doB().doC()
ดังนั้นฉันเคยได้ยินคนในอดีตต่อต้านอินเทอร์เฟซคล่องแคล่วเพราะพวกเขาชอบรูปแบบแรก ชื่ออื่นที่ฉันได้ยินสำหรับ "ส่วนต่อประสานที่คล่องแคล่ว" คือ "train wreck";)
ฉันพูดว่า "มากกว่าหรือน้อยกว่าที่เทียบเท่า" เพราะอินเตอร์เฟซที่คล่องแคล่วเพิ่มริ้วรอย พวกเขาไม่ต้อง "ส่งคืนสิ่งนี้" พวกเขาสามารถ "คืนใหม่" นั่นเป็นวิธีการบรรลุวัตถุที่ไม่เปลี่ยนรูปใน OO
ดังนั้นคุณสามารถมีคลาส A ที่ทำ (pseudocode)
function doA():
return new A(value + 1)
function doB():
return new A(value * 2)
function doC():
return new A(sqrt(value))
ตอนนี้แต่ละเมธอดจะส่งคืนออบเจ็กต์ใหม่โดยไม่เปลี่ยนออบเจ็กต์เริ่มต้น และนั่นเป็นวิธีที่จะเข้าไปในวัตถุที่ไม่เปลี่ยนรูปได้โดยไม่ต้องเปลี่ยนโค้ดของคุณมากนัก
new(...)
นั่นจะทำให้หน่วยความจำรั่ว
__init__
ซ้ำ ๆ จะแนะนำค่าใช้จ่ายด้วย
ภาษาส่วนใหญ่ตระหนักถึงสำนวน 'คืนตนเอง' และไม่สนใจหากไม่ได้ใช้ในบรรทัด อย่างไรก็ตามเป็นที่น่าสังเกตว่าใน Python ฟังก์ชั่นจะส่งกลับNone
โดยค่าเริ่มต้น
เมื่อฉันอยู่ในโรงเรียน CS ผู้สอนของฉันทำเรื่องใหญ่เกี่ยวกับความแตกต่างระหว่างฟังก์ชั่นขั้นตอนและกิจวัตร คำถามเรียงความที่เป็นตะคริวมือหลายข้อเริ่มต้นด้วยดินสอกลที่กำลังร้อนแรงอยู่ในมือของฉันเกี่ยวกับสิ่งที่
พอจะพูดได้ว่าการส่งคืนตนเองเป็นวิธี OO ขั้นสุดท้ายในการสร้างคลาสวิธี แต่ Python อนุญาตให้ส่งคืนค่าหลายรายการอันดับรายการวัตถุดั้งเดิมหรือไม่มี
การผูกมัดตามที่พวกเขาทำนั้นเป็นเพียงการใส่คำตอบสำหรับการปฏิบัติการครั้งสุดท้ายในครั้งถัดไปและการรันไทม์ของ Python สามารถปรับให้เหมาะสมกับสิ่งนั้น รายการความเข้าใจเป็นรูปแบบในตัวนี้ (ทรงพลังมาก!)
ดังนั้นใน Python มันไม่สำคัญที่ทุกเมธอดหรือฟังก์ชั่นจะส่งคืนสิ่งต่าง ๆ ซึ่งเป็นเหตุผลว่าทำไมค่าเริ่มต้นคือไม่มี
มีโรงเรียนแห่งความคิดที่ว่าทุกการกระทำในโปรแกรมควรรายงานความสำเร็จความล้มเหลวหรือผลลัพธ์กลับสู่บริบทหรือวัตถุที่กล่าวอ้าง แต่แล้วก็ไม่ได้พูดถึงข้อกำหนดของ DOD ADA ที่นี่ หากคุณต้องการรับคำติชมจากวิธีใดให้ดำเนินการต่อไปหรือไม่ แต่พยายามที่จะสอดคล้องกับมัน
หากวิธีการล้มเหลวควรกลับสู่ความสำเร็จหรือล้มเหลวหรือเพิ่มข้อยกเว้นที่จะจัดการ
หนึ่งข้อแม้คือถ้าคุณใช้สำนวนตัวเองคืน Python จะอนุญาตให้คุณกำหนดวิธีการทั้งหมดให้กับตัวแปรและคุณอาจคิดว่าคุณได้รับผลข้อมูลหรือรายการเมื่อคุณได้รับวัตถุจริง
ประเภทที่ จำกัด ภาษากรีดร้องและตะโกนและแตกเมื่อคุณพยายามทำเช่นนี้ แต่การตีความภาษา (Python, Lua, Lisp) นั้นมีความหลากหลายมากกว่า
ในสมอลทอล์คทุกวิธีที่ไม่ส่งคืนอย่างชัดเจนมี "คืนตัวเอง" โดยปริยาย
นั่นเป็นเพราะ (ก) การที่ทุกวิธีส่งคืนบางสิ่งทำให้โมเดลการคำนวณมีความเหมือนกันมากขึ้นและ (ข) มันมีประโยชน์มากที่วิธีการคืนค่าตัวเอง Josh K เป็นตัวอย่างที่ดี
Python
ทุกวิธีที่ไม่ส่งคืนอย่างชัดเจนมีนัย "ส่งคืนไม่มี"
return self
)ตัวอย่าง:
print(foo.modify1().modify2())
# instaed of
foo.modify1()
foo.modify2()
print(foo)
รูปแบบที่นิยมมากขึ้นในชุมชนการเขียนโปรแกรม (ฉันคิดว่า)
return self
)return
เพื่อวัตถุประสงค์อื่น