在我的在线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
如何成为抽象类?
答案 0 :(得分:8)
我担心你的在线课程会让你的连锁店稍微扯一下。他们在那里写的“答案”就是简单的继承。没有abc(抽象基类)模块,实际上并没有任何“抽象”Python类,至少在其他语言没有的意义上。你最接近的可能是定义引发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
类“抽象”,因为它不包含您在子类中可能需要的所有方法,但实际上这并不是一个有意义的事情 - 它就像调用任何类一样具有子类“abstract”的原因只是因为它的子类定义了一个新方法。
答案 1 :(得分:1)
看看the ABC module。这允许您使用abastract方法定义抽象类。作为一项教育练习,您也可以尝试使用元类来实现自己的,但只需重新发明轮子以了解其工作原理。