ThatTechGuy
ThatTechGuy

Reputation: 889

Python Abstract Attribute

I will only have a single Abstract Class in this particular module and so I'm trying to avoid importing the "ABC" package. See below for my attempt and the issue I'm running into. I only want to use basic self.attribute = {etc...} assignment in the __init__ method of the subclass but I want to ensure it is done via the AbstractClass. I've seen some questions here but the answers all reference "ABC" package which I would agree is the best solution but not for simply one class in an entire program...

from .util import EventType, NpcType


class Event(object):
    @property
    def requirements(self):
        raise NotImplementedError('subclasses must have requirements')

    @requirements.setter
    def requirements(self, value):
        pass

    def stage(self):
        raise NotImplementedError('subclasses must override stage()')


class NRMSAL(Event):
    def __init__(self):
        self.requirements = {
            'npc_type': [NpcType.TRAPPER],
            'last_event': [],
            'cash_available': False,
            'item_available': True
        }

    def stage(self):
        pass

In the above example I receive the following error when attempting to access the attribute at run time:

from drapi.event import NRMSAL
test = NRMSAL()
print test.requirements
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Users/rickmartin/Dropbox/Projects/NpcProject/drapi/event.py", line 7, in requirements
    raise NotImplementedError('subclasses must have requirements')
NotImplementedError: subclasses must have requirements

Upvotes: 1

Views: 2276

Answers (1)

Jonathan
Jonathan

Reputation: 8890

You're expecting each child class to have self.requirements right? So change the following code to this.

class Event(object):
    @property
    def requirements(self):
        try:
            return self._requirements
        except AttributeError:
            raise NotImplementedError('subclasses must have requirements')

That way it will return self.requirements. If self.requirements hasn't been implemented by the child class it will raise a not implemented error.

EDIT: Updated return to avoid never-ending loop.

Upvotes: 1

Related Questions