คำตอบนี้มีจุดมุ่งหมายเพื่ออธิบายมิกซ์อินพร้อมด้วยตัวอย่างที่:
อยู่ในตัวเอง : สั้น ๆ โดยไม่จำเป็นต้องรู้จักห้องสมุดใด ๆ เพื่อทำความเข้าใจกับตัวอย่าง
ใน Pythonไม่ใช่ภาษาอื่น
เป็นที่เข้าใจได้ว่ามีตัวอย่างจากภาษาอื่นเช่น Ruby เนื่องจากคำนี้มีอยู่ทั่วไปในภาษาเหล่านั้นมากขึ้น แต่นี่เป็นPython thread
นอกจากนี้ยังจะต้องพิจารณาคำถามแย้ง:
จำเป็นต้องมีการสืบทอดหลายรายการหรือไม่แสดงลักษณะมิกซ์อินหรือไม่?
คำนิยาม
ฉันยังไม่เห็นการอ้างอิงจากแหล่ง "เชิงอำนาจ" อย่างชัดเจนว่ามิกซ์อินในงูใหญ่คืออะไร
ฉันได้เห็นคำจำกัดความที่เป็นไปได้ 2 ข้อของมิกซ์อิน (ถ้าพวกเขาจะได้รับการพิจารณาว่าแตกต่างจากแนวคิดที่คล้ายกันอื่น ๆ เช่นคลาสฐานนามธรรม) และผู้คนไม่เห็นด้วยกับสิ่งที่ถูกต้อง
ฉันทามติอาจแตกต่างกันในแต่ละภาษา
คำจำกัดความที่ 1: ไม่มีการสืบทอดหลายรายการ
มิกซ์อินเป็นคลาสที่เมธอดของคลาสใช้เมธอดที่ไม่ได้กำหนดไว้ในคลาส
ดังนั้นคลาสไม่ได้มีเจตนาให้เป็นอินสแตนซ์ แต่ให้ใช้เป็นคลาสพื้นฐาน มิฉะนั้นอินสแตนซ์จะมีวิธีการที่ไม่สามารถเรียกได้โดยไม่มีข้อยกเว้น
ข้อ จำกัด ที่บางแหล่งที่มาเพิ่มคือคลาสอาจไม่มีข้อมูลวิธีการ แต่ฉันไม่เห็นว่าทำไมถึงมีความจำเป็น อย่างไรก็ตามในทางปฏิบัติ mixins ที่มีประโยชน์มากมายไม่มีข้อมูลใด ๆ และคลาสพื้นฐานที่ไม่มีข้อมูลนั้นง่ายต่อการใช้งาน
ตัวอย่างคลาสสิกคือการใช้งานตัวดำเนินการเปรียบเทียบทั้งหมดจากเท่านั้น<=
และ==
:
class ComparableMixin(object):
"""This class has methods which use `<=` and `==`,
but this class does NOT implement those methods."""
def __ne__(self, other):
return not (self == other)
def __lt__(self, other):
return self <= other and (self != other)
def __gt__(self, other):
return not self <= other
def __ge__(self, other):
return self == other or self > other
class Integer(ComparableMixin):
def __init__(self, i):
self.i = i
def __le__(self, other):
return self.i <= other.i
def __eq__(self, other):
return self.i == other.i
assert Integer(0) < Integer(1)
assert Integer(0) != Integer(1)
assert Integer(1) > Integer(0)
assert Integer(1) >= Integer(1)
# It is possible to instantiate a mixin:
o = ComparableMixin()
# but one of its methods raise an exception:
#o != o
ตัวอย่างนี้สามารถทำได้โดยใช้functools.total_ordering()
มัณฑนากร แต่เกมที่นี่คือการคิดค้นล้อใหม่:
import functools
@functools.total_ordering
class Integer(object):
def __init__(self, i):
self.i = i
def __le__(self, other):
return self.i <= other.i
def __eq__(self, other):
return self.i == other.i
assert Integer(0) < Integer(1)
assert Integer(0) != Integer(1)
assert Integer(1) > Integer(0)
assert Integer(1) >= Integer(1)
คำจำกัดความที่ 2: การสืบทอดหลายรายการ
mixin เป็นรูปแบบการออกแบบซึ่งวิธีการบางอย่างของคลาสฐานใช้วิธีที่ไม่ได้กำหนดและวิธีการดังกล่าวมีวัตถุประสงค์เพื่อนำไปใช้กับคลาสฐานอื่นไม่ได้มาจากคำนิยามที่ 1
คำว่าmixin classหมายถึงคลาสพื้นฐานที่มีจุดประสงค์เพื่อใช้ในรูปแบบการออกแบบนั้น (สิ่งที่ต้องทำที่ใช้วิธีหรือสิ่งที่ใช้มัน)
มันไม่ใช่เรื่องง่ายที่จะตัดสินใจว่าคลาสที่กำหนดนั้นเป็นมิกซ์มินหรือไม่: วิธีการนั้นสามารถนำไปใช้กับคลาสที่ได้รับมาซึ่งในกรณีนี้เรากลับไปที่นิยาม 1 คุณต้องพิจารณาความตั้งใจของผู้เขียน
รูปแบบนี้น่าสนใจเพราะเป็นไปได้ที่จะรวมฟังก์ชันการทำงานที่มีตัวเลือกต่าง ๆ ของคลาสพื้นฐานไว้:
class HasMethod1(object):
def method(self):
return 1
class HasMethod2(object):
def method(self):
return 2
class UsesMethod10(object):
def usesMethod(self):
return self.method() + 10
class UsesMethod20(object):
def usesMethod(self):
return self.method() + 20
class C1_10(HasMethod1, UsesMethod10): pass
class C1_20(HasMethod1, UsesMethod20): pass
class C2_10(HasMethod2, UsesMethod10): pass
class C2_20(HasMethod2, UsesMethod20): pass
assert C1_10().usesMethod() == 11
assert C1_20().usesMethod() == 21
assert C2_10().usesMethod() == 12
assert C2_20().usesMethod() == 22
# Nothing prevents implementing the method
# on the base class like in Definition 1:
class C3_10(UsesMethod10):
def method(self):
return 3
assert C3_10().usesMethod() == 13
หลามเผด็จการเกิดขึ้น
ที่documentatiton อย่างเป็นทางการสำหรับ collections.abcเอกสารอย่างชัดเจนใช้คำว่าวิธี Mixin
มันระบุว่าถ้าชั้นเรียน:
- การดำเนินการ
__next__
- สืบทอดมาจากคลาสเดียว
Iterator
จากนั้นชั้นเรียนจะได้รับ__iter__
วิธีมิกซ์อินฟรี
ดังนั้นอย่างน้อยในจุดนี้ของเอกสารคู่มือmixin ไม่ต้องการการสืบทอดหลายแบบและสอดคล้องกับข้อกำหนด 1
แน่นอนว่าเอกสารอาจขัดแย้งกับจุดต่าง ๆ และห้องสมุด Python สำคัญอื่น ๆ อาจใช้คำจำกัดความอื่นในเอกสารประกอบ
หน้านี้ยังใช้คำศัพท์Set mixin
ซึ่งแสดงให้เห็นอย่างชัดเจนว่าคลาสที่ต้องการSet
และIterator
สามารถเรียกคลาส Mixin ได้
ในภาษาอื่น ๆ
Ruby: เห็นได้ชัดว่าไม่ต้องการการสืบทอดหลายรายการสำหรับมิกซ์อินดังที่กล่าวไว้ในหนังสืออ้างอิงที่สำคัญเช่นการเขียนโปรแกรม Rubyและภาษาการเขียนโปรแกรม Ruby
C ++: วิธีการที่ไม่ได้ใช้งานเป็นวิธีเสมือนจริง
นิยาม 1 เกิดขึ้นพร้อมกับคำจำกัดความของคลาสนามธรรม (คลาสที่มีวิธีเสมือนจริง) คลาสนั้นไม่สามารถสร้างอินสแตนซ์ได้
นิยาม 2 เป็นไปได้ด้วยการสืบทอดเสมือน: การสืบทอดหลายรายการจากสองคลาสที่ได้รับ