In Python, are blends equivalent to compositions? If so, why not just use the composition?

I understand mixin as something like inheritance, but more like composition.
(edit: I tend to think of giving additional functionality/attributes from mixin, rather than giving another is-a relationship .)
Mentally, I say something like this when I use mixin: I give you this mix that you are missing, instead of what you really are this mixin type. (Is-a)

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

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

If I must guess, is it because my_instance.foo () is simpler 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 combine another_instance as an attribute of my_instance)

Is there any other reason?


Edit:

So, although I feel that he is, a mixin still has a relationship. and you get the benefit when you use it - it's a clean interface. This is "how I interpret the delnan answer.

+7
python inheritance mixins composition
source share
1 answer

(Since mixin does not give you the is-a relationship, it gives you -a)

Wrong, this gives you an is-a relationship. Consider class C(A, B) . issubclass(C, A) true, and therefore issubclass(C, B) . Calling C().method_of_B() calls method B if it is not overridden somewhere in the MRO (which could happen with one inheritance!), And similarly for methods A Access to the attribute C().attr_of_{a,b} also gives attribute A or B (the same warning as methods).

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

This rule of thumb exists because many people tend to use inheritance where it is not appropriate, and not because inheritance is not a useful tool in any case. This also applies to Python. Common (good) reasons include:

  • A - the attitude would be wrong, for example, because it violates the principle of Liskov substitution. This reason is not affected by mixins, see above.
  • Composition is simpler or less error prone, for various reasons. This reason is valid when mixins are possible, if something is amplified, as it can be a little complicated ( although not impossible ) to get the MRO and the super() sequence calls right.

If I must guess, is it because my_instance.foo () is simpler than my_instance.another_instance.foo ()?

These are just a few extra characters. More importantly, you need to re-type the wrapper methods for each method that you want to re-export (that would be all of them if you emulate is-a relationships through composition).

More conceptually, this manual work seems pointless and error prone if C really is-a A Mixins / multiple inheritance supports the case when an object is larger than one that can or should be represented by a single bass class. For example, a UTF-8 string can be either a ByteBuffer or a UnicodeStream . In general, we have interfaces for this (or not, in Python it is implicit), but mixins also allow you to add related functions in a convenient and convenient way.

+7
source share

All Articles