1

I have a class design where theChildren classes inheriting from a certainParent class just differ in someparameters, but theParent class contains all methods, which are using theparameters provided as class variables on theChildren. So, in other words, each of myChild classes is fully described by the list ofparameters and the inheritance of theParent class.

So, let's say, I have the following classes:

class Parent():    def __init__(self, **kwargs):        for param in self.__class__.parameters:            self.setattr(param, kwargs.get(param))    def compare(self, other):        for param in self.__class__.parameters:            if self.getattr(param) != other.getattr(param):                return False        return Trueclass ChildA(Parent):    parameters = ["length", "height", "width"]    def __init__(self, **kwargs):        super().__init__(**kwargs)class ChildB(Parent):    parameters = ["color", "taste"]    def __init__(self, **kwargs):        super().__init__(**kwargs)

My actual classes are a bit different - I have more and more complex methods on theParent class and also different kinds of parameters - , but this is sort of a minimum example of the design principle.

SinceParent class is relying on itsChildren to have the class variableparameters, I thought, I might want to enforce the existence of the class variable on eachChild class. I have read that I achieve this by using a metaclass. But I have also read that most developers do not need to use metaclasses, and if in doubt, you probably don't need them. I have never worked with metaclasses before, and so I am in doubt whether I should use them, and so by that rule mentioned, I probably do not need a metaclass. But on the other hand, the term "metaclass" just sounds like a good match to my structure, sinceParent really looks like something which could well be called "metaclass" in some sense (technically, not in terms of the way the terminus technicusmetaclass is used in OOP, but in terms of: it is fully describing the behaviour of the children classes).

So, I wonder: Is there a different (better) design of classes to reflect my structure? Should I use a metaclass to enforce the existence of theparameters, or is there a better way to do so? Or should I just resign to enforce the existence of theparameters class variable on the Children classes in the first place?

Paradox's user avatar
Paradox
81814 silver badges30 bronze badges
askedMar 24, 2019 at 3:27
Jonathan Herrera's user avatar
2
  • Why would you not define interfaces (or for that matter actual method implementations) in the parent class that deal with the parameters visible to the parent and override them in the child class dealing with additional parameters in the child class?CommentedMar 24, 2019 at 5:24
  • @Sharad: In my situation, I have a bunch of methods and a bunch of Child classes. I would like to avoid the need to implement the methods on each Child class. The idea of that design is to avoid repetitive code on each Child class. But I am not sure, whether I fully understood what you mean. Could you make an example? That would help me clearly understanding you, I guess.CommentedMar 24, 2019 at 9:44

1 Answer1

1

If using python3.6 or above, you can accomplish this using__init_subclass__ which I personally reason better with than a metaclass.

An example of__init_subclass__ based on the usecase described:

class Parent:    def __init_subclass__(cls):        if not hasattr(cls, 'parameters'):          raise TypeError(f'Subclass of {cls} does not have a parameters class attribute')    def __init__(self, **kwargs):        for param in self.__class__.parameters:            self.setattr(param, kwargs.get(param))    def compare(self, other):        for param in self.__class__.parameters:            if self.getattr(param) != other.getattr(param):                return False        return Trueclass GoodChild(Parent):    parameters = ['length', 'height', 'width']class BadChild(Parent):    pass

Which results in raising aTypeError exception when theBadChild class is created (not when it is instantiated):

TypeError: Subclass of <class '__main__.BadChild'> does not have a parameters class attribute
answeredMar 24, 2019 at 5:29
salparadise's user avatar
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.