jedmao
jedmao

Reputation: 10512

Should I be using abstract methods in this Python scenario?

I'm not sure my approach is good design and I'm hoping I can get a tip. I'm thinking somewhere along the lines of an abstract method, but in this case I want the method to be optional. This is how I'm doing it now...

from pymel.core import *

class A(object):
    def __init__(self, *args, **kwargs):
        if callable(self.createDrivers):
            self._drivers = self.createDrivers(*args, **kwargs)
            select(self._drivers)

class B(A):
    def createDrivers(self, *args, **kwargs):
        c1 = circle(sweep=270)[0]
        c2 = circle(sweep=180)[0]
        return c1, c2

b = B()

In the above example, I'm just creating 2 circle arcs in PyMEL for Maya, but I fully intend on creating more subclasses that may or may not have a createDrivers method at all! So I want it to be optional and I'm wondering if my approach is—well, if my approach could be improved?

Upvotes: 2

Views: 3288

Answers (3)

XORcist
XORcist

Reputation: 4367

I would do this:

class A(object):
    def __init__(self, *args, **kwargs):
        self.createDrivers(*args, **kwargs)

    def createDrivers(self, *args, **kwargs):
        "Override"
        pass

class B(A):
    def createDrivers(self, *args, **kwargs):
        self._drivers = blabla

Upvotes: 2

Lennart Regebro
Lennart Regebro

Reputation: 172407

If you want createDrivers to be optional but still always there, the best is not an abstract method, but do implement it in the base class as a noop.

class A(object):
    def __init__(self, *args, **kwargs):
        self._drivers = self.createDrivers(*args, **kwargs)
        select(self._drivers)

    def createDrivers(self, *args, **kwargs):
        """This should be overridden by subclasses if they need custom drivers"""
        pass

Upvotes: 1

mouad
mouad

Reputation: 70079

You still have a problem, when you will inherit your class B, and this will call A.__init__ and if you don't implement createDrivers in the subclass this line callable(self.createDrivers) will throw an error as that createDrivers doesn't exist (AttributeError) i think if i were you i will do it like so:

class A(object):
    def __init__(self, *args, **kwargs):
       try:
           self._drivers = self.createDrivers(*args, **kwargs)
           select(self._drivers)
       except NotImplementedError:
           pass

    def createDrivers(self, *args, **kwargs):
        raise NotImplementedError("This class wasn't implemented")

class B(A):
    def createDrivers(self, *args, **kwargs):
        c1 = circle(sweep=270)[0]
        c2 = circle(sweep=180)[0]
        return c1, c2

class C(A):
    pass

Another way is to replace callable(self.createDrivers) by hasattr(self, 'createDrivers').

Upvotes: 3

Related Questions