How to declare instance variables in abstract class?

Question:

class ILinkedListElem:
    @property
    def value(self):
        raise NotImplementedError

    @property
    def next(self):
        raise NotImplementedError


class ListElem(ILinkedListElem):
    def __init__(self, value, next_node=None):
        self.value = value
        self.next = next_node

I wanna something like this. This abstract variables definition works for class vars, but not for instance

I want to all instances of ILinkedListElem subclass must has "value" and "next" attributes

Asked By: KrySeyt

||

Answers:

If you want to force/require all instances of any subclass of ILinkedListElem to have the attributes "value" and "nxt", the following standard implementation with abstractmethod seems to do what you’re after:

from abc import ABC, abstractmethod

class ILinkedListElem (ABC):
    @property
    @abstractmethod
    def value(self):
        raise NotImplementedError

    @property
    @abstractmethod
    def nxt(self):
        raise NotImplementedError

This is the abstract class, from which we create a compliant subclass:

class ListElem_good (ILinkedListElem):
    
    def __init__(self, value, next_node=None):
        self._value = value
        self._nxt = next_node
        
    @property
    def value(self):
        return self._value
    
    @property
    def nxt(self):
        return self._nxt

We create an instance of this compliant subclass and test it:

x = ListElem_good('foo', 'bar')
print (x.value)
print (x.nxt)

#result:
    # foo
    # bar

If we create a non-compliant subclass that omits an implementation of nxt, like so:

class ListElem_bad (ILinkedListElem):
    
    def __init__(self, value):
        self._value = value
        
        
    @property
    def value(self):
        return self._value

when we try to create an instance of this non-compliant subclass:

y = ListElem_bad('foo')
print (y.value)

it fails:

    y = ListElem_bad('foo')

TypeError: Can't instantiate abstract class ListElem_bad with abstract methods nxt

This relies on essentially the same solution offered here, which you suggested in a comment-exchange does not meet your requirements. But when applied to your specific use-case above, it appears to precisely address the issue you’ve raised – or have I misunderstood?

Answered By: Vin