在类中重写函数的最紧凑和最简洁的方法是啥?
Posted
技术标签:
【中文标题】在类中重写函数的最紧凑和最简洁的方法是啥?【英文标题】:The most compact and neat way about overriding a function in a class?在类中重写函数的最紧凑和最简洁的方法是什么? 【发布时间】:2018-11-09 14:40:59 【问题描述】:我正在尝试编写一个用于文本操作的类。这个想法是类将支持基本的文本预处理,但如果有人想编写一个非常复杂的预处理函数,他们应该能够使用基类并覆盖它。我尝试了以下方法,即使我可以以某种方式使其工作,但我认为这不是正确的方法。
class TextPreprocessor:
def __init__(self, corpus):
"""Text Preprocessor base class.
corpus: a list of sentences
"""
self.corpus = corpus
self.word_tokens = [self.preprocess(sentence) for sentence in corpus]
def preprocess(self,sentence):
"""
strip each sentence , lowercase it and split by space # sentence.strip().lower().split()
"""
return sentence.strip().lower().split()
def preprocess_transform(self,sentence):
return self.preprocess(sentence)
现在,如果我想编写一个新的预处理函数,这是最好的方法。我试过了,
class SubPreprocess(TextPreprocessor):
def __init__(self, corpus):
#### dummy preprocess function
def preprocess(self, sentence):
return sentence.strip().split() + ['HELLOOOOOOOOOOLLLL']
super.__init__(corpus)
它不工作。我基本上想要的是预处理函数(修改后的),应该能够覆盖基类TextPreprocessor
中的那个,这样当__init__
被调用时,self.word_tokens
,应该基于新的预处理函数
【问题讨论】:
你为什么要newting__init__
中的函数?
【参考方案1】:
以下会做:
class SubPreprocess(TextPreprocessor):
def preprocess(self, sentence):
return sentence.strip().split() + ['HELLOOOOOOOOOOLLLL']
如果你现在调用SubPreprocess
的构造函数,将会使用新的preprocess
方法:
proc = SubPreprocess(some_corpus)
# looks up any methods in the mro of SubPreprocess
【讨论】:
有意思,没想到这样做也继承了init函数 @Karl 否则,继承将毫无用处。您只需覆盖需要更改的方法。当这些被其他方法调用时,self.__class__
的mro 确定查找顺序。
我做了同样的事情,但没有成功。但是,现在当我查看我的代码时,我意识到,在创建 SubPreprocess
类之后,我在不知不觉中调用了 TextPreprocessor
。这是最好的方法。谢谢。赞成。 :-)
@Karl - 这是首选,因为对使用基类感兴趣但只想更改preprocess
函数的人应该远离额外的复杂性。就是这样。
@schwobaseggl,是的,这很清楚。不知何故,我从来没有想过这也适用于__init__
。在我看到的几乎每个关于如何在 Python 中处理继承的示例中,子类总是有自己的构造函数,而超类是从那里显式调用的。很高兴在周五下午学习一些整洁的东西【参考方案2】:
class SubPreprocess(TextPreprocessor):
def __init__(self, corpus):
#this is how you initialise the superclass
super(SubPreprocess, self).__init__(corpus)
# the overridden function should be within the scope of the class, not under the initializer
def preprocess(self, sentence):
return sentence.strip().split() + ['HELLOOOOOOOOOOLLLL']
【讨论】:
【参考方案3】:如果你想注入行为,只需使用一个函数:
class TheAlgorithm:
def __init__(self, preprocess):
self.preprocess = preprocess
def process(self, corpus):
after_a = self.part_a(corpus)
preprocessed = self.preprocess(after_a)
return self.part_b(preprocessed)
使用非常简单:
p = TheAlgorithm(lambda c: c.strip().split() + 'helllol')
p.process('the corpus')
实际上,如果你的类只是存储一些函数,你可以进行全功能编程:
def processor(preprocess):
def algorithm(corpus):
return part_b( preprocess(corpus) )
p = processor(lambda c: "-".join(c.split(",")))
assert "a-b-c" == p("a,b,c")
【讨论】:
【参考方案4】:尝试更改:super.init(语料库) 到 super().init(语料库)
【讨论】:
以上是关于在类中重写函数的最紧凑和最简洁的方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章