In Python, are mixins equivalent to composition? If so, then why not just use composition?

↘锁芯ラ 提交于 2021-02-18 22:36:02

问题


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.

We could just use straight compositions instead of mixins, what is mixin for?

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)

Are there any other reason?


Edit:

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.


回答1:


(Since mixin doesn't give you is-a relationship, it gives you has-a)

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).

And I read few times, you should prefer composition over inheritance.

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:

  • 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.

If I have to guess, it's because my_instance.foo() is easier than my_instance.another_instance.foo()?

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).

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.



来源:https://stackoverflow.com/questions/17630148/in-python-are-mixins-equivalent-to-composition-if-so-then-why-not-just-use-co

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!