我的问题是指在一个函数中组织多次需要的代码,而不是在其他地方。
假设以下用例:
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更少。
有没有其他方法,或者我应该选择这里显示的三种方法之一?