I'm fully aware that pylint and other static analysis tools are not all-knowing, and sometimes their advice must be disobeyed. (This applies for various classes of messages, not just conventions.)

If I have classes like

class related_methods():

    def a_method(self):

class more_methods():

    def b_method(self):

class implement_methods(related_methods, more_methods):

    def __init__(self):
        self.stack  = some()
        self.my_var = other()

    def otherfunc(self):

Obviously, that's contrived. Here's a better example, if you like.

I believe this style is called using "mixins".

Like other tools, pylint rates this code at -21.67 / 10, primarily because it thinks more_methods and related_methods don't have self or attributes otherfunc, stack, annd my_var because without running the code, it apparently can't see related_methods and more_methods are mixed-in to implement_methods.

Compilers and static analysis tools can't always solve the Halting Problem, but I feel this is certainly a case in which looking at what's inherited by implement_methods would show this is perfectly valid, and that would be a very easy thing to do.

Why do static analysis tools reject this valid (I think) OOP pattern?


  1. They don't even try to check inheritance or

  2. mixins are discouraged in idiomatic, readable Python

#1 is obviously incorrect because if I ask pylint to tell me about a class of mine that inherits unittest.TestCase that uses self.assertEqual, (something defined only in unittest.TestCase), it does not complain.

Are mixins unpythonic or discouraged?

  • 3
    Is this a bad question? Is is off-topic? is it unanswerable? Am I stupid? People can DV but they don't want to help improve it. – cat Mar 10 '16 at 15:55
  • 1
    There some that are likely tired of having people ask "is this an (anti-)pattern" or "is this (un)pythonic". – user40980 Mar 10 '16 at 15:58
  • 11
    @MichaelT That's fine. They can stop reviewing questions then. – Katana314 Mar 10 '16 at 16:56
  • 2
    @tac people will downvote for various reasons, but are never required to say why - the downvote button has a tool-tip that says, "this question does not show any research effort; it is unclear or not useful" - a vague, if acceptable answer. 8 up and 1 down is actually pretty good, particularly on a question, where downvotes are free. Don't let it get you down. Cheers. – Aaron Hall Mar 10 '16 at 20:20
  • @AaronHall I'm aware people are allowed to do what they like with their votes, indeed I tell new users who complain the same thing. – cat Mar 10 '16 at 20:23

Mixins just aren't a use case that was considered by the tool. That doesn't mean it's necessarily a bad use case, just an uncommon one for python.

Whether mixins are used appropriately in a particular instance is another matter. The mixin anti-pattern I see most frequently is using mixins when there is only ever intended to be one combination mixed. That's just a roundabout way to hide a god class. If you can't think of a reason right now to swap out or leave out one of the mixins, it shouldn't be a mixin.

  • yeah, it's a god object, I admit. In this case I'd argue it's OK for the CPU to be a god object. – cat Mar 12 '16 at 3:55

I believe that Mixins can, absolutely, be Pythonic. However, the idiomatic way to silence your linter--and improve your Mixins' readability--is to both (1) define abstract methods that explicitly define the methods that a Mixin's children are required to implement, and to (2) pre-define None-valued fields for Mixin data members that children must initialize.

Applying this pattern to your example:

from abc import ABC, abstractmethod

class related_methods():
    my_var = None
    stack = None

    def a_method(self):

class more_methods(ABC):
    def otherfunc(self):

    def b_method(self):

class implement_methods(related_methods, more_methods):
    def __init__(self):
        self.stack  = some()
        self.my_var = other()

    def otherfunc(self):
  • 2
    +1 for your answer, although the abstract other(self): pass thing trades the linter's confusion for mine – cat Aug 10 '17 at 23:47
  • It's even more confusing without the @abstractmethod ;-) I started with Java first so this is just fine for me. – Chris Huang-Leaver Apr 18 '19 at 4:53
  • 1
    One important fact to allow mixin be Pythonic (from the maintenable facet) is to refuse inheritance in mixins. Initialization with mixins is MRO dependant, and if a root ancestor don't call super().__init__ the chain is broken. – gdoumenc Jan 23 '20 at 15:16
  • 1
    @gdoumenc Could you elaborate that a bit? – ruohola Jun 13 '20 at 12:26

The linter is not aware that you use a class as a mixin. Pylint is aware that you use a mixin if you add the suffix 'mixin' or 'Mixin' at the end of the class name, then the linter stops complaining.

linter_without_mixins linter2_with_mixin

Mixins aren't bad or good per se, are just a tool. You make them a good use or a bad use.

  • Would it be better to declare the fields from subclasses that are needed by the mixin? – olyk Jun 5 '20 at 7:14
  • Actually, is there a way to declare abstract fields? This would properly force their implementation. – olyk Jun 5 '20 at 7:15

I think mixins can be good, but I also think pylint is right in this case. Disclaimer: opinion-based stuff follows.

A good class, mixins included, has one clear responsibility. Ideally, a mixin should carry all the state it is going to access, and the logic to handle it. E.g. a good mixin could add a last_updated field to an ORM model class, provide logic for setting it, and methods to search for the oldest / newest record.

Referring to undeclared instance members (variables and methods) does look a bit weird.

The right approach very much depends on the task at hand.

It may be a mixin with the relevant bit of state kept in it.

It may be a different class hierarchy where the methods that you currently distribute via a mixin are in a base class, while lower-level implementation differences belong to subclasses. This looks most fit for your case with the stack operations.

It may be a class decorator that adds a method or two; this usually makes sense when you have to pass some arguments to the decorator to affect the method generation.

State your problem, explain your bigger design concerns, then we could argue if something is an anti-pattern in your case.


Are mixins ok?

Are Python mixins an anti-pattern?

Mixins are not discouraged - they are a good use-case for multiple inheritance.

Why is your linter complaining?

Pylint is obviously complaining because it doesn't know where the otherfunc, stack, and my_var is coming from.


There is no immediately apparent good reason for you separate these two methods into separate parent classes, either in your example in the question, or in your more trivial linked example, shown here.

202 class OpCore():
203     # nothing runs without these
205 class OpLogik(): 
206     # logic methods... 
208 class OpString(): 
209     # string things
212 class Stack(OpCore, OpLogik, OpString): 
214     "the mixin mixer of the above mixins" 

Costs of mixins and noise

The costs of what you are doing is making your linter report noise. That noise may obscure more important problems with you code. This is an important cost to weigh. Another cost is that you're separating your inter-related code into different namespaces that may make it harder for programmers to discover the meaning of.


Inheritance allows for code reuse. If you get code reuse with your mixins, great, they've created value for you that probably outweighs the possible other costs. If you're not getting code reuse/deduplication of lines of code, you're probably not getting much value for your mixins, and at that point, I think the cost of the noise is greater than the benefits.

  • 1
    There's a good reason for seprating them in the linked, nontrivial example -- it's easier for me to organise my code when I have a fraction of a full class that implements math, another that implements strings, and so on, and you mix them together to get Forth Soup. – cat Mar 10 '16 at 17:54
  • "Another cost is that you're separating your code into different namespaces that may make it harder for programmers to discover the meaning of" -- no, that's not the case at all. The class namespaces make it easier to tell what a group of methods do, and when someone wants to use the stack, they should call / implement the Forth Soup, not the individual ingredients – cat Mar 10 '16 at 18:07
  • @cat probably because they're contrived and not used in a real large project, neither example really supports your points of using mixins. Both show only one time the mixin is used, in which case just putting the implementation in one place is better style and organization. Now if you could show a case where you want common features across classes but do not want a common base class, that's where you'd use a mixin. Which is beside your linting question (UltraBird answered that well). But this answers your question generally regarding mixin applicability. – dlamblin May 1 '18 at 2:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.