用Python方式仅在一个函数中重用代码的方法

我的问题是组织一个函数中多次需要的代码,而没有其他地方。


假设以下用例:


class A(object):

    def __init__(self, base):

        self.base = base


    def foo(self):

        result = self.base + 2    # Should go to an extra function.

        result = result * 4

        if result > 10:

            result = result + 2   # Should go to an extra function.

        return result


    def bar(self):

        pass

有一个在一个重复foo()与x + 2部分,这在我的项目是20行代码(将值添加到另一个对象的20个属性)应该被抽象。但是这些放在哪里呢?我看到三种方法来做到这一点:


(1.)嵌套函数:


class A(object):

    # ...


    def foo(self):

        def plus_two(value):

            return value + 2


        result = plus_two(self.base)

        result = result * 4

        if result > 10:

            result = plus_two(result)

        return result


    # ...

这似乎是有道理的,因为它是一个非常特定的用例,仅与方法内部发生的事情有关。


但是:无法测试,不能从外部访问嵌套函数进行单元测试。我真的不想对此进行测试作为一部分的foo(),因为这需要测试所有的plus_two两倍(因为如果这两种情况下)。在单元测试中,它应该是可以测试plus_two分开,只有其正确调用在foo()。


(2.)辅助方法:


class A(object):

    # ...


    def foo(self):

        result = self.plus_two(self.base)

        result = result * 4

        if result > 10:

            result = self.plus_two(result)

        return result


    def plus_two(self, value):

        return value + 2


    # ...

但是:该方法已经并且永远不会被该类中的任何其他方法使用,也不需要访问self,因此它不应成为该类的方法。在不需要访问对象或不需要作为接口一部分覆盖的类中收集函数不是pythonic。


(3.)一个模块功能:


def plus_two(value):

    return value + 2


class A(object):

    # ...


    def foo(self):

        result = plus_two(self.base)

        result = result * 4

        if result > 10:

            result = plus_two(result)

        return result


    # ...

但是:这导致一些辅助函数从其非常特定的上下文中删除,换句话说,没有遵循封装。虽然这似乎不是问题,可能似乎是解决方案,但在我的项目中,这确实会使整个模块变得混乱,因为该功能通常与该模块无关,但正如上面所说的,非常具体换句话说:将其拆分到与其上下文相距甚远的某个位置,这会使代码的可读性和python的可读性大大降低。


还有其他方法,还是应该从此处显示的三种方法中选择一种?


慕容3067478
浏览 127回答 2
2回答

浮云间

我肯定希望真实的例子更加复杂:)我会说去嵌套或辅助功能。我个人会去使用辅助函数,但这只是我的意见。当然,这是我可以告诉您的描述。实际代码将为建议提供更好的依据,而不仅仅是一个随机示例。

胡说叔叔

我个人认为选项1或2是最干净的。如您所提到的,选项3是非常特定于上下文的,可以定义为模块功能。要在选项1或2之间进行选择,您需要确定对单元代码进行单元测试的重要性。考虑到您已经基本回答了单元测试的重要性以及是否可以从foo()进行单元测试的问题,而且我真的不想在foo()中测试它那么您将需要使用选项2的一些变体。理想情况下,私有方法将是您的理想之选,但是由于python不支持该方法,因此至少应考虑为其命名。__plus_two()这是有关Python中领先的双下划线的相关问题:对象名称前的单下划线和双下划线是什么意思?这是另一个与私有方法有关的问题:为什么Python的“私有”方法实际上不是私有的?
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python