Reputation: 1216
I work on a project with a huge class. Initially they were implemented as functions that just get imported, like in this answer:
def plot(self, x, y):
print(self.field)
def clear(self):
# body
@classmethod
def from_file(cls, path):
# body
class Fitter(object):
def __init__(self, whatever):
self.field = whatever
# Imported methods
from .some_file import plot, clear, from_file
...
But I think it's not the best solution, IDE is mad on the code because it cannot find field
in the external methods and considers classmethod
on some functions as an error. I hope mixins can help with it.
But I see the similar problem in this approach: mixin classes don't have a base class with all the common methods and fields specified (an example in Django), so IDE and linters cannot find definitions and understand the code correctly too... I tried to use some common base class, as the following:
class FitterBase(object):
def __init__(self, whatever):
self.field = whatever
class FiterMixin(FitterBase):
def plot(self, x, y):
print(self.field)
def clear(self):
# body
@classmethod
def from_file(cls, path):
# body
class Fitter(FitterBase, FiterMixin):
pass
But the interpreter raises an error:
TypeError: Cannot create a consistent method resolution
Is there any solution to this problem? It's really important because the class contains dozens of big methods, and correct inheritance would help a lot.
Upvotes: 1
Views: 2903
Reputation: 531490
Python is trying to construct an MRO for Fitter
in which FitterBase
both precedes and follows FitterMixin
; the former because FitterBase
is listed first in the seance of base classes, the latter because it is the parent of FitterMixin
.
To resolve that issue, simply swap the order of the two base classes:
class Fitter(FitterMixin, FitterBase):
pass
There's no reason to list both, though, because FitterMixin
already inherits from FitterBase
:
class Fitter(FitterMixin):
pass
As this makes more obvious, FitterMixin
isn't really a mix-in class, because you aren't mixing it with anything. Or, don't make FitterMixin
subclass FitterBase
:
class FitterBase:
def __init__(self, whatever):
self.field = whatever
class FitterMixin:
def plot(self, x, y):
print(self.field)
def clear(self):
pass
@classmethod
def from_file(cls, path):
pass
class Fitter(FitterBase, FitterMixin):
pass
Upvotes: 1