请注意以下方法:
def _locate(self, text):
"""
This method accesses preceding locators if these exist, it then calls an overridable helper method called _relocate
which receives text with readjusted boundaries and searches inside, the basic implemented behaviour is that of a logical or
"""
if not self.precedents:
for sub_segment in self._relocate(text, Segment(0, len(text), 1)):
if self._multiple:
yield sub_segment
elif self.max_segment.prob > self._prob_threshold:
yield self.max_segment
return
else:
for precedent in self.precedents:
for segment in precedent.locate(text):
for sub_segment in self._relocate(text, segment):
if self._multiple:
yield sub_segment
elif self.max_segment.prob > self._prob_threshold:
yield self.max_segment
return
# if we haven't found a good enough segment return the best one we came across while locating
if not self._multiple:
yield self.max_segment
它有一些重复的代码两次:
for sub_segment in self._relocate(text, segment):
if self._multiple:
yield sub_segment
elif self.max_segment.prob > self._prob_threshold:
yield self.max_segment
return
我天真地以为我可能会定义一个单独的帮助器方法并且只需要一次代码就可以开始实现它,然而,事实证明这几乎是不可能的(因为代码同时使用了yield和return)并且导致了我在代码长度和运行时方面更加痛苦。
不确定我究竟在问什么(如果有什么我可能会问是否有人知道一些共享生成器代码的一般方法,或者看看如何在这里完成?),但无论如何作为发电机的话题,我发现这个经历非常有说服力,所以我想我会分享。
答案 0 :(得分:1)
我认为你可以通过定义循环外部段的生成器来删除代码重复
def _locate(self, text):
"""
This method accesses preceding locators if these exist, it then calls an overridable helper method called _relocate
which receives text with readjusted boundaries and searches inside, the basic implemented behaviour is that of a logical or
"""
if self.precedents:
segments = (seg for precedent in self.precedents for seg in precedent.locate(text))
else:
segments = (Segment(0, len(text), 1),)
for segment in segments:
for sub_segment in self._relocate(text, segment):
if self._multiple:
yield sub_segment
elif self.max_segment.prob > self._prob_threshold:
yield self.max_segment
return
# if we haven't found a good enough segment return the best one we came across while trying
if not self._multiple:
yield self.max_segment