python abstract attribute (not property)
Question: What's the best practice to define an abstract instance attribute, but not as
a property?

I would like to write something like:

    
    
    class AbstractFoo(metaclass=ABCMeta):
    
        @property
        @abstractmethod
        def bar(self):
            pass
    
    class Foo(AbstractFoo):
    
        def __init__(self):
            self.bar = 3
    

Instead of:

    
    
    class Foo(AbstractFoo):
    
        def __init__(self):
            self._bar = 3
    
        @property
        def bar(self):
            return self._bar
    
        @bar.setter
        def setbar(self, bar):
            self._bar = bar
    
        @bar.deleter
        def delbar(self):
            del self._bar
    

Properties are handy, but for simple attribute requiring no computation they
are an overkill. This is especially important for abstract classes which will
be subclassed and implemented by the user (I don't want to force someone to
use `@property` when he just could have written `self.foo = foo` in the
`__init__`).

[Abstract attributes in
Python](http://stackoverflow.com/questions/2736255/abstract-attributes-in-
python) question proposes as only answer to use `@property` and
`@abstractmethod`: it doesn't answer my question.

<http://code.activestate.com/recipes/577761-simple-abstract-constants-to-use-
when-abstractprop/> may be the right way, but I am not sure. It also only
works with class attributes and not instance attributes.


Answer: If you really want to enforce that a subclass define a given attribute, you
can use metaclass. Personally, I think it may be overkill and not very
pythonic, but you could do something like this:

    
    
     class AbstractFooMeta(type):
    
         def __call__(cls, *args, **kwargs):
             """Called when you call Foo(*args, **kwargs) """
             obj = type.__call__(cls, *args, **kwargs)
             obj.check_bar()
             return obj
    
    
     class AbstractFoo(object):
         __metaclass__ = AbstractFooMeta
         bar = None
    
         def check_bar(self):
             if self.bar is None:
                 raise NotImplementedError('Subclasses must define bar')
    
    
     class GoodFoo(AbstractFoo):
         def __init__(self):
             self.bar = 3
    
    
     class BadFoo(AbstractFoo):
         def __init__(self):
             pass
    

Basically the meta class redefine `__call__` to make sure `check_bar` is
called after the init on an instance.

    
    
    GoodFoo()  # ok
    BadFoo ()  # yield NotImplementedError
    

