3

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

假设以下用例:

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测试两次(对于两个 if 情况)。在单元测试中,应该可以单独测试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

    # ...

但是:这会导致几个辅助函数脱离其非常特定的上下文,换句话说,不遵循封装。虽然这在这里似乎不是问题并且可能似乎是解决方案,但在我的项目中,这确实会使整个模块变得混乱,因为该功能通常与模块无关,但正如所说,非常具体到它使用的那个方法。换句话说:把它拆分到离它的上下文很远的地方,它使代码的可读性和pythonic更少。

有没有其他方法,或者我应该选择这里显示的三种方法之一?

4

2 回答 2

0

就个人而言,我认为选项 1 或 2 是最干净的。正如您所提到的,选项 3 是非常特定于上下文的,被定义为模块功能。

要在选项 1 或 2 之间做出决定,您需要确定能够对特定代码段进行单元测试的重要性。考虑到您已经基本回答了单元测试的重要性以及是否可以从 foo() 中对其进行单元测试的问题,

而且我真的不想将其作为 foo() 的一部分进行测试

那么你需要使用选项 2 的一些变体。理想情况下,私有方法将是这里的方法,但由于 python 不支持,至少考虑命名它__plus_two()这是一个有关 Python 中前导双下划线的相关问题:对象名称前的单下划线和双下划线是什么意思?这是另一个与私有方法相关的问题:为什么 Python 的“私有”方法实际上不是私有的?

于 2013-06-05T10:58:11.677 回答
0

我当然希望真实的例子更复杂:)

我会说去嵌套或辅助功能。我个人会选择辅助功能,但这只是我的意见。这当然是从你的描述中可以看出的。实际代码将为建议提供更好的基础,而不仅仅是一个随机示例。

于 2013-06-05T10:04:50.147 回答