การพิมพ์เป็ดคืออะไร


429

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

"การพิมพ์เป็ด" คืออะไร?


1
@ มิทช์ฉันพยายามและได้รับบางสิ่งบางอย่างเป็นรูปแบบของการสืบทอด แต่ไม่สามารถทำตามได้มากนัก ขออภัยถ้าฉันถามคำถามผิด
sushil bharwani

3
@sushil bharwani: ไม่ไม่โกรธ แต่ผู้คนคาดหวังว่าในฐานะที่เป็นพอร์ตแรกของการโทร (เช่นสิ่งแรกที่คุณทำ) คือการลองค้นหาก่อนโพสต์ที่นี่
มิทช์ข้าวสาลี

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

41
ฉันแน่ใจว่าฉันได้อ่านที่ไหนสักแห่งที่ SO ตั้งใจจะให้เป็น "คลังเก็บคำถามที่เป็นที่ยอมรับ" และฉันค่อนข้างมั่นใจว่าคุณจะไม่ได้รับที่ยอมรับมากกว่านี้
heltonbiker

คำตอบ:


302

มันเป็นคำที่ใช้ในภาษาแบบไดนามิกที่ไม่ได้มีการพิมพ์ที่แข็งแกร่ง

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

ชื่อนี้มาจากวลี "ถ้ามันดูเหมือนเป็ดและต้มตุ๋นเหมือนเป็ดมันก็เป็นเป็ด"

Wikipediaมีข้อมูลมากมาย


25
ระวังการใช้งานพิมพ์ดีดแรง มันไม่ได้กำหนดไว้อย่างดี ไม่มีการพิมพ์ดีดเป็ด Google Go หรือ Ocaml เป็นภาษาที่พิมพ์แบบคงที่ด้วยโครงสร้างย่อยการก่อสร้าง ภาษาเป็ดเหล่านี้พิมพ์หรือไม่
ฉันให้คำตอบ CRAP

7
วลีที่ดีกว่าสำหรับการพิมพ์เป็ดคือ: "ถ้ามีคนบอกว่ามันเป็นเป็ด .. ก็ดีพอสำหรับฉัน" ดูpyvideo.org/video/1669/keynote-3 28:30 หรือyoutube.com/watch?v=NfngrdLv9ZQ#t=1716
tovmeod

7
การพิมพ์เป็ดไม่จำเป็นต้องใช้ในภาษาแบบไดนามิกเสมอไป Objective-C ไม่ใช่ภาษาไดนามิกและใช้การพิมพ์เป็ด
eyuelt

12
ทั้ง Python และ Ruby เป็นภาษาที่แข็งแกร่งและทั้งคู่มี Duck Typing การพิมพ์สตริงไม่ได้หมายความว่าไม่มีการพิมพ์เป็ด
alanjds

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

209

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

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

ตัวอย่างงาน:เรียกวิธีการบางอย่างQuackบนวัตถุ

โดยไม่ต้องใช้เป็ดพิมพ์, ฟังก์ชั่นการทำงานนี้มีการระบุล่วงหน้าว่าอาร์กิวเมนต์มีการสนับสนุนวิธีการบางอย่างf Quackวิธีทั่วไปคือการใช้อินเทอร์เฟซ

interface IQuack { 
    void Quack();
}

void f(IQuack x) { 
    x.Quack(); 
}

การโทรf(42)ล้มเหลว แต่f(donald)ทำงานได้นานตราบเท่าที่donaldเป็นอินสแตนซ์ของIQuack-subtype

อีกวิธีคือการพิมพ์โครงสร้าง - แต่อีกครั้งวิธีการที่Quack()ระบุไว้อย่างเป็นทางการทุกสิ่งที่ไม่สามารถพิสูจน์ได้ว่ามันquackจะทำให้เกิดความล้มเหลวในการรวบรวมล่วงหน้า

def f(x : { def Quack() : Unit }) = x.Quack() 

เราสามารถเขียนได้

f :: Quackable a => a -> IO ()
f = quack

ใน Haskell โดยที่Quackabletypeclass ช่วยให้แน่ใจว่ามีวิธีการของเรา


ดังนั้นการพิมพ์เป็ดเปลี่ยนได้อย่างไร

อย่างที่ฉันได้กล่าวไปแล้วว่าระบบการพิมพ์เป็ดไม่ได้ระบุข้อกำหนด แต่เพียงลองใช้งานถ้ามีอะไรเกิดขึ้น

ดังนั้นระบบพิมพ์แบบไดนามิกที่ Python ใช้การพิมพ์แบบเป็ดเสมอ:

def f(x):
    x.Quack()

หากfได้รับการxสนับสนุนQuack()ทุกอย่างก็โอเคถ้าไม่มันจะพังเมื่อรันไทม์

แต่การพิมพ์เป็ดไม่ได้หมายถึงการพิมพ์แบบไดนามิกเลยจริงๆแล้วมีวิธีการพิมพ์เป็ดที่ได้รับความนิยมอย่างมาก

template <typename T>
void f(T x) { x.Quack(); } 

ฟังก์ชั่นไม่ได้บอกในทางที่มันต้องการบางอย่างxที่สามารถทำได้Quackดังนั้นแทนที่จะพยายามรวบรวมเวลาและถ้าทุกอย่างใช้งานได้มันก็โอเค


5
ไม่ได้หมายถึง: void f (IQuak x) {x.Quak (); } (แทน K.Quack) เนื่องจากพารามิเตอร์ของฟังก์ชัน f คือ IQuack x ไม่ใช่ Iquack k, มีข้อผิดพลาดเล็กน้อย แต่ฉันรู้สึกว่ามันจำเป็นต้องได้รับการแก้ไข :)
Dominicbri7

ตามวิกิพีเดียตัวอย่างสุดท้ายของคุณคือ "โครงสร้างการพิมพ์" ไม่ใช่ "การพิมพ์เป็ด"
Brilliand

ดูเหมือนว่ามีคำถามแยกต่างหากสำหรับการสนทนานี้: stackoverflow.com/questions/1948069/…
Brilliand

1
ดังนั้นถ้าฉันเข้าใจสิ่งที่คุณพูดความแตกต่างระหว่างภาษาที่รองรับการพิมพ์เป็ดกับที่ไม่ได้เป็นเพียงแค่การพิมพ์เป็ดคุณไม่จำเป็นต้องระบุประเภทของวัตถุที่ฟังก์ชั่นยอมรับ แทนdef f(x) def f(IQuack x)
PProteus

124

คำอธิบายอย่างง่าย (ไม่มีรหัส)

การอภิปรายความหมายของคำถามนั้นค่อนข้างเหมาะสม (และเป็นเรื่องทางวิชาการ) แต่เป็นแนวคิดทั่วไป:

พิมพ์ดีดเป็ด

(“ ถ้ามันเดินเหมือนเป็ดและ quacks เหมือนเป็ดก็เป็นเป็ด”) - ใช่! แต่นั่นหมายความว่ายังไง ?? นี่คือตัวอย่างที่ดีที่สุดโดย:

ตัวอย่างการทำงานของ Duck Typing:

ลองนึกภาพฉันมีไม้เท้าวิเศษ มันมีพลังพิเศษ ถ้าฉันโบกมือพูดว่า"ขับ!" สำหรับรถยนต์แล้วมันก็ขับ!

มันทำงานกับสิ่งอื่น ๆ ? ไม่แน่ใจ: ดังนั้นฉันลองบนรถบรรทุก ว้าว - มันก็เหมือนกัน! จากนั้นฉันก็ลองใช้บนเครื่องบินรถไฟและ 1 วูดส์ (เป็นไม้กอล์ฟชนิดหนึ่งที่ผู้คนใช้ในการ 'ขับ' ลูกกอล์ฟ) พวกเขาทั้งหมดขับรถ!

แต่มันจะใช้งานได้ไหมว่าเป็นถ้วยน้ำชา? ข้อผิดพลาด: KAAAA-BOOOOOOM! ที่ไม่ได้ผลดีมาก ====> ถ้วยชาขับไม่ได้ !! duh !?

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

ในคำอื่น ๆ ที่เรามีความสนใจในสิ่งที่วัตถุที่สามารถทำได้มากกว่ากับสิ่งที่เป็นวัตถุ

ตัวอย่าง: ภาษาที่พิมพ์แบบคงที่

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

กล่าวอีกนัยหนึ่งในสถานการณ์นี้ไม้กายสิทธิ์มองอย่างใกล้ชิดในสิ่งที่วัตถุคือ (เป็นรถหรือไม่) มากกว่าสิ่งที่วัตถุสามารถทำได้ (เช่นรถยนต์รถบรรทุก ฯลฯ สามารถขับได้)

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

สรุป: กุญแจนำออก

สิ่งที่สำคัญในการพิมพ์เป็ดเป็นสิ่งที่วัตถุจริงสามารถทำมากกว่าสิ่งที่วัตถุที่เป็น


ฉันพบว่าหลักฐานที่น่าสนใจเกี่ยวกับคุณสนใจมากขึ้นเกี่ยวกับพฤติกรรมนั่นเป็นคำจำกัดความ ไม่ต้องสงสัยเลยว่า BDD ประสบความสำเร็จในภาษาอย่างทับทิม
Pablo Olmos de Aguilera C.

27

พิจารณาว่าคุณกำลังออกแบบฟังก์ชั่นที่เรียบง่ายซึ่งได้รับวัตถุประเภทBirdและเรียกwalk()วิธีการของมัน มีสองวิธีที่คุณสามารถนึกถึง:

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

จะต้องพิจารณาว่าการพิมพ์เป็ดอาจมีประโยชน์ในบางกรณีเช่น Python ใช้การพิมพ์เป็ดมาก


การอ่านที่มีประโยชน์


1
คำอธิบายที่ดีมีข้อได้เปรียบอะไรบ้าง?
sushil bharwani

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

18

Wikipedia มีคำอธิบายโดยละเอียดอย่างเป็นธรรม:

http://en.wikipedia.org/wiki/Duck_typing

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

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


13

ฉันเห็นคำตอบมากมายที่ซ้ำสำนวนเก่า:

ถ้ามันดูเหมือนเป็ดและต้มตุ๋นเหมือนเป็ดมันก็เป็นเป็ด

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

ฉันไม่พบความช่วยเหลือมากนัก

นี่เป็นความพยายามที่ดีที่สุดในการตอบคำถามภาษาอังกฤษแบบธรรมดาเกี่ยวกับการพิมพ์เป็ดที่ฉันได้พบ:

การพิมพ์ดีดเป็ดหมายถึงวัตถุที่ถูกกำหนดโดยสิ่งที่มันสามารถทำได้ไม่ได้โดยสิ่งที่มันเป็น

ซึ่งหมายความว่าเราไม่เกี่ยวข้องกับคลาส / ชนิดของวัตถุและเกี่ยวข้องกับวิธีการใดที่สามารถเรียกใช้บนมันและการดำเนินการใดที่สามารถทำได้บนมัน เราไม่ได้ดูแลเกี่ยวกับเรื่องของชนิดเราดูแลเกี่ยวกับสิ่งที่สามารถทำได้


3

พิมพ์เป็ด:

หากมันพูดและเดินเหมือนเป็ดเป็ดก็จะเป็นเช่นนั้น

นี้มักจะเรียกว่าการลักพาตัว ( abductiveเหตุผลหรือเรียกอีกอย่างว่าretroductionความหมายที่ชัดเจนผมคิดว่า):

  • จากC (สรุป, สิ่งที่เราเห็น ) และR (กฎ, สิ่งที่เรารู้ ), เรายอมรับ / ตัดสินใจ / ถือว่าP (สถานที่, คุณสมบัติ ) ในคำอื่น ๆ ความจริงที่กำหนด

    ... พื้นฐานการวินิจฉัยทางการแพทย์

    กับเป็ด: C = เดินพูดคุย , R = เหมือนเป็ด , P = มันเป็นเป็ด

กลับไปที่การเขียนโปรแกรม:

  • วัตถุoมีเมธอด / คุณสมบัติmp1และอินเตอร์เฟส / ชนิดT ต้องการ / กำหนดmp1

  • วัตถุoมีเมธอด / คุณสมบัติmp2 และอินเตอร์เฟส / ประเภทTต้องการ / กำหนดmp2

  • ...

ดังนั้นมากกว่าแค่ยอมรับmp1 ... บนวัตถุใด ๆ ตราบเท่าที่มันตรงกับคำจำกัดความของmp1 ... , คอมไพเลอร์ / รันไทม์ก็ควรจะโอเคกับการยืนยันoเป็นประเภทT

และเป็นกรณีตัวอย่างข้างต้น? การพิมพ์ Duck นั้นไม่มีการพิมพ์เลยใช่ไหม? หรือเราควรเรียกมันว่าการพิมพ์โดยนัย?


3

การดูภาษานั้นอาจช่วยได้ มันมักจะช่วยฉัน (ฉันไม่ใช่เจ้าของภาษา)

ในduck typing:

1) คำtypingไม่ได้หมายถึงการพิมพ์บนแป้นพิมพ์ (เช่นเดียวกับที่เป็นภาพติดตาในใจของฉัน) มันหมายถึงการพิจารณา " สิ่งที่ประเภทของสิ่งที่เป็นสิ่งที่? "

2) คำนี้duckแสดงให้เห็นว่าการกำหนดนั้นทำได้อย่างไร; มันเป็นการตัดสินใจแบบ 'หลวม' เช่นเดียวกับใน: " ถ้ามันเดินเหมือนเป็ด ... มันก็เป็นเป็ด " มัน 'หลวม' เพราะสิ่งนี้อาจเป็นเป็ดหรืออาจจะไม่ แต่จริง ๆ แล้วมันเป็นเป็ดไม่สำคัญ สิ่งสำคัญคือฉันสามารถทำอะไรกับมันได้ฉันสามารถทำอะไรกับเป็ดได้และคาดว่าพฤติกรรมที่แสดงออกโดยเป็ด ฉันสามารถให้อาหารมันกับเศษขนมปังและสิ่งที่อาจเข้าหาฉันหรือพุ่งเข้าใส่ฉันหรือถอยออกไป ... แต่มันจะไม่กลืนกินฉันเหมือนอย่างหงุดหงิด


2

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

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

ตัวอย่างเช่นคุณอาจกำลังเขียนชุดคำสั่งเพื่อเพิ่มข้อมูลเพลงลงในสตริง หากคุณมาจากพื้นหลัง C # หรือ Java คุณอาจถูกล่อลวงให้เขียนสิ่งนี้:

def append_song(result, song)
    # test we're given the right parameters 
    unless result.kind_of?(String)
        fail TypeError.new("String expected") end
    unless song.kind_of?(Song)
        fail TypeError.new("Song expected")
end

result << song.title << " (" << song.artist << ")" end
result = ""

append_song(result, song) # => "I Got Rhythm (Gene Kelly)"

ยอมรับการพิมพ์เป็ดของ Ruby และคุณจะเขียนอะไรที่ง่ายกว่านี้:

def append_song(result, song)
    result << song.title << " (" << song.artist << ")"
end

result = ""
append_song(result, song) # => "I Got Rhythm (Gene Kelly)"

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


2

พิมพ์ดีดเป็ดไม่ได้พิมพ์คำใบ้!

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

คุณสามารถจินตนาการระบบที่จัดเก็บข้อมูล ในการเขียน / อ่านข้อมูลคุณจำเป็นต้องมีพื้นที่เก็บข้อมูลและข้อมูลบางประเภท

ประเภทของการจัดเก็บอาจ: ไฟล์ฐานข้อมูลเซสชั่น ฯลฯ

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

ทุกระบบจัดเก็บข้อมูลจะต้องรู้ว่ามีอินเทอร์เฟซอยู่หรือไม่โดยใช้วิธีการเดียวกัน

interface StorageInterface
{
   public function write(string $key, array $value): bool;
   public function read(string $key): array;
}


class File implements StorageInterface
{
    public function read(string $key): array {
        //reading from a file
    }

    public function write(string $key, array $value): bool {
         //writing in a file implementation
    }
}


class Session implements StorageInterface
{
    public function read(string $key): array {
        //reading from a session
    }

    public function write(string $key, array $value): bool {
         //writing in a session implementation
    }
}


class Storage implements StorageInterface
{
    private $_storage = null;

    function __construct(StorageInterface $storage) {
        $this->_storage = $storage;
    }

    public function read(string $key): array {
        return $this->_storage->read($key);
    }

    public function write(string $key, array $value): bool {
        return ($this->_storage->write($key, $value)) ? true : false;
    }
}

ดังนั้นทุกครั้งที่คุณจำเป็นต้องเขียน / อ่านข้อมูล:

$file = new Storage(new File());
$file->write('filename', ['information'] );
echo $file->read('filename');

$session = new Storage(new Session());
$session->write('filename', ['information'] );
echo $session->read('filename');

ในตัวอย่างนี้คุณจะใช้ Duck Typing ใน Constructor Storage:

function __construct(StorageInterface $storage) ...

หวังว่ามันจะช่วย;)


2

Tree Traversal ด้วยเทคนิคการพิมพ์เป็ด

def traverse(t):
    try:
        t.label()
    except AttributeError:
        print(t, end=" ")
    else:
        # Now we know that t.node is defined
        print('(', t.label(), end=" ")
        for child in t:
            traverse(child)
        print(')', end=" ")

0

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


-1

ฉันพยายามที่จะเข้าใจประโยคที่โด่งดังในแบบของฉัน: "Python ปริมาณไม่สนใจวัตถุเป็นเป็ดจริงหรือไม่ทั้งหมดที่มันสนใจก็คือไม่ว่าจะเป็นวัตถุแรก 'ต้มตุ๋น' ที่สอง 'เหมือนเป็ด'

มีเว็บไซต์ที่ดี http://www.voidspace.org.uk/python/articles/duck_typing.shtml#id14

ผู้เขียนชี้ให้เห็นว่าการพิมพ์เป็ดช่วยให้คุณสร้างคลาสของคุณเองที่มีโครงสร้างข้อมูลภายในของตนเอง - แต่เข้าถึงได้โดยใช้ไวยากรณ์ Python ปกติ

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