问题描述
我将mixin理解为看起来像继承,但更像是组合.
(我倾向于认为通过混合而不是给予另一个is-a关系来赋予其他功能/属性.)
心理上,当我使用mixin时,我是在说这样的话:我给您这个mixin是您所缺少的,而不是您实际上也是这种mixin类型.(is-a)
I understand mixin as what looks like inheritance but what is more like composition.
(edit: I tend to think giving additional functionality/attributes
by mixin rather than giving another is-a relationship
.)
Mentally, I'm saying something like this when I use mixin: I'm giving you this mixin you are missing, rather than you are actually this mixin-type as well.(is-a)
我读过几次,您应该更喜欢组合而不是继承.
And I read few times, you should prefer composition over inheritance.
我们可以直接使用合成而不是mixin,mixin的作用是什么?
We could just use straight compositions instead of mixins, what is mixin for?
如果我不得不猜测,那是因为my_instance.foo()比my_instance.another_instance.foo()容易吗?
(如果mixin具有foo(),则可以使用my_instance.foo();将another_instance组合为my_instance的属性时,需要my_instance.another_instance.foo())
If I have to guess, it's because my_instance.foo() is easier than my_instance.another_instance.foo()?
(You can use my_instance.foo() if mixin has foo(), you need my_instance.another_instance.foo() when you composite another_instance as an attribute of my_instance)
还有其他原因吗?
所以,即使我觉得它具有-a,mixin仍然是-a关系.当您使用is-a时会获得好处,这是更干净的界面.这就是我解释德尔南答案的方式.
So even though I feel it's has-a, mixin is still is-a relationship. and benefit you get when you use is-a here is, cleaner interface. That' how I interpret delnan's answer.
推荐答案
错,它的确给了您is-a关系.考虑 C(A,B)
类. issubclass(C,A)
为true, issubclass(C,B)
也是如此.调用 C().method_of_B()
会调用B的方法,如果该方法未在MRO的某处被覆盖(也可能发生在单个继承中!),同样,对于的方法一个
.属性访问 C().attr_of_ {a,b}
也为您提供了 A
或 B
的属性(与方法相同)
Wrong, it does give you a is-a relationship. Consider class C(A, B)
. issubclass(C, A)
is true and so is issubclass(C, B)
. The call C().method_of_B()
calls the method of B if it isn't overridden somewhere in the MRO (which can happen with single inheritance too!), and similarly for methods of A
. The attribute access C().attr_of_{a,b}
gives you an attribute of A
or B
too (same caveat as with methods).
存在此经验法则是因为许多人倾向于在不合适的地方使用继承,而不是因为在任何情况下继承都不是有用的工具.这也适用于Python.常见(好的)原因包括:
This rule of thumb exists because many people tend to use inheritance where it isn't appropriate, not because inheritance isn't a useful tool in any case. This applies to Python too. Common (good) reasons include:
- 一个is-a关系将是错误的,例如因为它违反了Liskov替代原则.这个原因不受mixins的影响,请参见上文.
- 由于各种原因,排版更容易或更容易出错.如果也可以使用mixin,则此原因是正确的,如果将其放大,则可能会有些棘手(尽管并非不可能)正确获得MRO和
super()
调用序列.
- A is-a relationship would be wrong, for example because it breaks the Liskov Substitution Principle. This reason is not affected by mixins, see above.
- Composition is easier or less error-prone, for various reasons. This reason is valid when mixins are possible too, if anything it's amplified as it can be a bit tricky (though not impossible) to get the MRO and sequence of
super()
calls right.
这只是几个额外的字符.更重要的是,您必须为每个要重新导出的方法重新键入包装器方法(如果您通过合成来模拟is-a关系,则它们将是 all ).
That's just a few additional characters. More important is that you have to re-type wrapper methods for every single method you want to re-export (which would be all of them if you're emulating an is-a relationship via composition).
从概念上讲,如果 C
确实是- A
,则此手册工作似乎毫无意义且容易出错.Mixins/多重继承支持对象超出单个低音类可以表示或应该表示的对象的情况.例如,UTF-8字符串可以是 ByteBuffer
和 UnicodeStream
.通常,我们有用于此的接口(或没有接口;在Python中是隐式的),但是mixins还允许以可组合且方便的方式添加相关功能.
More conceptually, this manual work seems pointless and error-prone if C
really is-a A
. Mixins/multiple inheritance support the case where an object is more than what can or should be represented by a single bass class. For example, a UTF-8 string may be both a ByteBuffer
and a UnicodeStream
. In general, we have interfaces for this (or not; in Python this is implicit), but mixins also allow adding related functionality in a composable and convenient manner.
这篇关于在Python中,mixins等同于组合吗?如果是这样,那为什么不仅仅使用合成呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!