1

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
2
  • In general, it seems wrong to make both a class attribute and base class method with the same name. One is a method and one is a dict, which is not callable. Commented Sep 9, 2017 at 17:14
  • @JacobIRR Sure, I agree... is there another way I can enforce the addition of a particular attribute regardless of its implementation? Commented Sep 9, 2017 at 17:26

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Fair enough, would I keep the setter as is or I don't need it? I included it because the property was becoming read only without it.
Just tried it... I actually get a recursion error in this case it's trying to "get the requirements over and over again" {File "/Users/rickmartin/Dropbox/Projects/DrugRunner/drapi/event.py", line 11, in requirements return self.requirements RuntimeError: maximum recursion depth exceeded}
There we go, I actually had this issue earlier, need to ensure the namespace is actually different so it doesn't continually return to itself... Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.