【发布时间】:2013-05-31 23:18:12
【问题描述】:
我的问题是指在一个函数中组织多次需要的代码,而不是在其他地方。
假设以下用例:
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
# ...
但是:这会导致几个辅助函数脱离其非常特定的上下文,换句话说,不遵循封装。虽然这在这里似乎不是问题并且可能似乎是解决方案,但在我的项目中,这确实会使整个模块变得混乱,因为该功能通常与模块无关,但正如所说,非常具体到使用它的那个方法。换句话说:把它拆分到离它的上下文很远的地方,它使代码的可读性和pythonic更少。
还有其他方式吗,还是我应该选择这里显示的三种方式之一?
【问题讨论】: