Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is an abstract class in python?

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?

like image 674
user2237529 Avatar asked Dec 27 '22 06:12

user2237529


1 Answers

It Isn't.

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.

like image 89
Henry Keiter Avatar answered Jan 16 '23 02:01

Henry Keiter