从屈服生成器函数中导出重复代码

问题描述 投票:1回答: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 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

我天真以为我可能会定义一个单独的帮助器方法并且只需要一次代码就可以开始实现它,然而,事实证明这几乎是不可能的(因为代码同时使用了产量和返回)并且让我更加痛苦在代码长度和运行时方面它是值得的。

不知道我究竟在问什么(如果有什么我可能会问是否有人知道共享生成器代码的一些通用方法,或者看看如何在这里完成?),但无论如何作为主题发电机去了我发现这个经历非常有说服力,所以我想我会分享。

python generator
1个回答
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
© www.soinside.com 2019 - 2024. All rights reserved.