[Tutor] a class that may not be instantiated
Oscar Benjamin
oscar.j.benjamin at gmail.com
Tue Nov 24 12:39:51 EST 2015
On 24 November 2015 at 15:36, Albert-Jan Roskam <sjeik_appie at hotmail.com> wrote:
> Hi,
>
> I have two classes with a number of methods that are the same, so I want to define a super class that holds these methods. But the super class (below called _Generic) should not be instantiated, because it serves no purpose other than the DRY principle. I raise a NotImplementedError in case if somebody dares to instantiate _Generic. Below, only one common method is defined in_Generic, namely __repr__ (the other ones are __enter__ and __exit__, maybe more, if you must know). At first I thought I'd need the abc module for this, but this seems to do the trick. I do not want to enforce concrete implementations of abstract methods, which is the goal of abc. Is this the way to do this, or this this quirky code?
>
> import inspect
>
> class _Generic(object):
>
> def __init__(self, *args, **kwargs):
> raise NotImplementedError
>
> def __repr__(self):
> fmt = []
> for arg in inspect.getargspec(self.__init__).args[1:]:
> value = getattr(self, arg)
> sr = "%r" if isinstance(value, basestring) else "%s"
> fmt.append(("%s=" + sr) % (arg, value))
> return self.__class__.__name__ + "(" + ", ".join(fmt) + ")"
I just wouldn't bother with this (personally).
Firstly why are you worried that someone will try to instantiate
_Generic? I don't imagine that I would if I was trying to use your
library since it has an underscore prefix and presumably your
user-facing docs don't mention it. You could make that more explicit
by putting the word Abstract into the class name or something.
Really though that class is just a function:
def my_repr_function(self):
fmt = []
for arg in inspect.getargspec(self.__init__).args[1:]:
value = getattr(self, arg)
sr = "%r" if isinstance(value, basestring) else "%s"
fmt.append(("%s=" + sr) % (arg, value))
return self.__class__.__name__ + "(" + ", ".join(fmt) + ")"
Then you can do:
class Concrete(Generic):
...
__repr__ = my_repr_function
I realise that in your actual case there are more methods but then
this can just be a mixin class. Then you can call it something with
Mixin in the name and again people will know not to use it (except in
inheritance).
--
Oscar
More information about the Tutor
mailing list