4

在我的在线 python 课程中,我有这个问题:

实现一个字触发器抽象类,WordTrigger。它应该接受一个字符串单词作为类的构造函数的参数。

这是作为解决方案发布的:

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())

我对抽象类的理解是抽象类是一个特殊的类,我们在其中定义要使用的方法而无需任何实现,因此当我们实例化一个对象并尝试访问该方法时,它不会给您带来任何实现错误。

WordTrigger抽象类如何?

4

2 回答 2

9

不是。

恐怕你的在线课程有点拉扯你的链条。他们在那里写的“答案”是简单的继承。如果没有abc(抽象基类)模块,就没有真正意义上的“抽象”Python 类,至少在其他语言拥有它的意义上没有。最接近的可能是定义 raise 的方法NotImplemented

class BaseClass(object):
    def evaluate(self, story):
        raise NotImplementedError('This is an "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...

这在语法上是可以的,甚至在某些情况下它甚至可以做你想让它做的事情,但一般来说,最好只编写你想要的方法,然后再覆盖它们。尤其如此,因为实际上并不能保证BaseClass.evaluate会保持“抽象”:我可以稍后(在定义类之后)来写BaseClass.evaluate = lambda self, story: None,这不仅是完全合法的,而且我还可以调用run实例BaseClass而不遇到NotImplementedError. _ 如果可以的话,最好完全远离这种事情。

您的在线课程称他们的课程为WordTrigger“抽象”,因为它不包含您在其子类中可能需要的所有方法,但实际上这并没有什么意义——这就像将任何具有子类的类称为“抽象”只是因为它的子类定义了一个新方法。

于 2013-04-02T19:39:58.950 回答
1

查看ABC 模块。这使您可以使用抽象方法定义抽象类。作为一种教育练习,您还可以尝试使用元类来实现自己的,但只是重新发明轮子来了解它是如何工作的。

于 2013-04-02T19:20:48.343 回答