Bu cevap, karışımları aşağıdaki örneklerle açıklamayı amaçlamaktadır :
kendine yeten : kısa, örneği anlamak için herhangi bir kütüphaneyi bilmenize gerek yok.
Python'da , diğer dillerde değil.
Terim bu dillerde çok daha yaygın olduğu için Ruby gibi diğer dillerden örnekler olduğu anlaşılabilir, ancak bu bir Python iş parçacığıdır.
Ayrıca tartışmalı soruyu da dikkate alacaktır:
Bir mixini karakterize etmek için birden fazla miras gerekli mi?
Tanımlar
Python'da bir mixin ne olduğunu açıkça söyleyen bir "yetkili" kaynaktan bir alıntı görmedim.
Bir mixinin 2 olası tanımını gördüm (eğer soyut temel sınıflar gibi diğer benzer kavramlardan farklı olarak düşünüleceklerse) ve insanlar hangisinin doğru olduğuna tamamen katılmıyorlar.
Fikir birliği farklı diller arasında değişebilir.
Tanım 1: Çoklu Kalıtım Yok
Bir mixin, sınıfın bazı yöntemlerinin sınıfta tanımlı olmayan bir yöntemi kullanacağı şekilde bir sınıftır.
Bu nedenle, sınıfın somutlaştırılması değil, temel bir sınıf olarak kullanılması amaçlanmıştır. Aksi takdirde, örnek bir istisna oluşturmadan çağrılamayan yöntemlere sahip olacaktır.
Bazı kaynakların eklediği bir kısıtlama, sınıfın veri içermeyebileceği, sadece yöntemler içerebileceği, ancak bunun neden gerekli olduğunu anlamıyorum. Bununla birlikte, pratikte, birçok yararlı karışımın herhangi bir verisi yoktur ve veri içermeyen temel sınıfların kullanımı daha kolaydır.
Klasik bir örnek sadece tüm karşılaştırma operatörleri uygulamasıdır <=
ve ==
:
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
Bu özel örnek functools.total_ordering()
dekoratör aracılığıyla elde edilebilirdi , ancak buradaki oyun tekerleği yeniden icat etmekti:
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)
Tanım 2: Çoklu Kalıtım
Bir mixin, baz sınıfın bazı yöntemlerinin tanımlanmadığı bir yöntemi kullandığı ve bu yöntemin başka bir baz sınıfı tarafından uygulanması amaçlanan bir tasarım modelidir. Tanım 1'deki gibi türetilmemiş bir .
Terimi mixin sınıfı bu tasarım modelinde kullanılabilir amaçlanan temel sınıfları belirtmektedir (yöntem kullananlar, veya uygulama o todo?)
Belirli bir sınıfın bir mixin olup olmadığına karar vermek kolay değildir: yöntem sadece türetilmiş sınıfta uygulanabilir, bu durumda Tanım 1'e geri dönüyoruz.
Bu model ilginçtir, çünkü farklı temel sınıf seçenekleriyle işlevsellikleri yeniden birleştirmek mümkündür:
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
Yetkili Python olayları
Koleksiyonlar için resmi belgeselde. Abc belgeleri açıkça Mixin Yöntemleri terimini kullanır .
Bir sınıf varsa:
- uygular
__next__
- tek bir sınıftan miras alır
Iterator
daha sonra sınıf ücretsiz bir __iter__
mixin yöntemi alır .
Bu nedenle, en azından dokümantasyonun bu noktasında, mixin çoklu kalıtım gerektirmez ve Tanım 1 ile uyumludur.
Belgeler elbette farklı noktalarda çelişkili olabilir ve diğer önemli Python kütüphaneleri belgelerindeki diğer tanımı kullanıyor olabilirler.
Bu sayfa aynı zamanda terimi kullandığı Set mixin
açıkça sınıfları gibi ileri sürmektedir, Set
ve Iterator
Mixin sınıfları çağrılabilir.
Diğer dillerde
Ruby: Ruby Programlama ve Ruby Programlama Dili gibi önemli referans kitaplarında belirtildiği gibi, mixin için açıkça birden fazla miras gerektirmez
C ++: Uygulanmayan bir yöntem, saf bir sanal yöntemdir.
Tanım 1, soyut bir sınıfın (saf sanal yöntemi olan bir sınıf) tanımıyla çakışır. Bu sınıf somutlaştırılamaz.
Tanım 2 sanal kalıtımla mümkündür: Türetilmiş iki sınıftan Çoklu Kalıtım