Reputation: 81
In my online python course, I had this question:
Implement a word trigger abstract class, WordTrigger. It should take in a string word as an argument to the class's constructor.
This was posted as the solution:
class WordTrigger(Trigger):
def __init__(self, word):
self.word = word
def isWordIn(self, text):
import string
for letter in text:
if letter in string.punctuation:
text = text.replace(letter, ' ', 1)
text = text.lower()
wordlist = text.split(' ')
if self.word.lower() in wordlist:
return True
return False
# TODO: TitleTrigger
class TitleTrigger(WordTrigger):
def evaluate(self, story):
return self.isWordIn(story.getTitle())
# TODO: SubjectTrigger
class SubjectTrigger(WordTrigger):
def evaluate(self, story):
return self.isWordIn(story.getSubject())
My understanding of an abstract class is abstract class is a special class in which we define the method to be used without any implementation, so when we instantiate an object and try to access the method it gives you no implementation error.
How is WordTrigger
an abstract class?
Upvotes: 4
Views: 4872
Reputation: 17168
I'm afraid your online course is yanking your chain a bit. What they've written there as the "answer" is simple inheritance. Without the abc (abstract base class) module, there's not really any such thing as an "abstract" Python class, at least not in the sense that other languages have it. The closest you can come is probably defining methods that raise NotImplemented
:
class BaseClass(object):
def evaluate(self, story):
raise NotImplementedError('This is an "abstract" method!')
That way at least makes subclasses override that method if they want to use it. You can further harass your users and come closer to a traditional "abstract class" by implementing other methods that call your "abstract" method:
# Don't do this!
class BaseClass(object):
def evaluate(self, story):
raise NotImplementedError('This is an "abstract" method!')
def run(self):
self.evaluate(None) #This will blow up until you implement self.evaluate!
# ... other code...
This is syntactically okay, and maybe it even does what you want it to do in some contexts, but generally, it's better just to write the methods you want and then override them later. This is especially true since there's actually no guarantee that BaseClass.evaluate
will remain "abstract": I could come along later (after the class is defined) and write BaseClass.evaluate = lambda self, story: None
and not only would that be perfectly legal, but I could then also call run
on instances of BaseClass
without encountering the NotImplementedError
. Better to stay away from this sort of thing altogether, if you can help it.
Your online course is calling their WordTrigger
class "abstract" because it doesn't contain all the methods you might want in its subclasses, but really that's not a meaningful thing to say--it's like calling any class that has subclasses "abstract" just because its subclasses define a new method.
Upvotes: 9
Reputation: 26160
Look at the ABC module. This lets you define abstract classes with abastract methods. As an educational exercise, you could also try to implement your own using metaclasses, but only reinvent the wheel to learn how it works.
Upvotes: 1