I’ve written the following code to help enforce the definition of certain methods for a class:
def createClassTemplate(name, requiredMethods=[], inherits=object):
def require(name):
def errorRaiser(self, *args, **kwargs):
raise RequireException("method '{}' must be defined.".format(name))
setattr(wrapper, "__name__", name)
return errorRaiser
class Custom(inherits): pass
setattr(Custom, "__name__", name)
for methodName in requiredMethods:
setattr(Custom, methodName, require(methodName))
return Custom
Which is implemented like this:
Model = createClassTemplate("Model", ["foo", "bar", "baz"])
class MyClass(Model):
pass
This way, when I’m missing a method, the calling class will generate a meaningful error indicating that I’ve failed to define a required method.
The problem is, the above code seems uncomfortably hacky and unpythonic. Am I going about this right way? Should I even be forcing class templates like this? And is there a better way to accomplish the same thing?
You should use a metaclass instead.
The standard library comes with a ready-made metaclass for just this task, the
ABCMetametaclass:Demonstration:
Once
MyClassdoes provide implementations of the abstract methods, instantiation succeeds: