简短的答案已经发布。使用实例变量( self.answer
):
class QuadEq(object):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def solve_quad_eq(self):
self.answer = ("this", "that")
return self.answer
def show_result(self):
print self.answer
eq = QuadEq(1,2,3)
eq.solve_quad_eq()
eq.show_result()
松散地说,实例变量(数据成员)只是一个生命周期与其“所有者”相同的变量(在示例中,被引用的对象eq
)。
现在,长篇大论——稍微有点迂腐——的回答是:在设计一个类时,你必须考虑它的职责和状态。简单地说,你上课的目的是什么?它只是各种或多或少相关功能的容器吗?在这种情况下,上述答案是完全可以接受的。但通常,您必须更加严格——至少为了提高代码的可理解性/可维护性。
在这里你有一QuadEq
堂课。顾名思义,我理解这个类的一个实例模型一个方程。由于这样一个方程的根是该方程的一个属性,我认为让该方法solve_quad_eq
成为该类的方法是可以接受的。稍作改动,我会使用更通用的名称solve
。为什么?因为这为提供相同语义的不同方程的未来类做准备。此外,返回结果并将其存储在实例变量中可能会造成混淆。你应该在这里做出选择。更不用说您的函数有时会返回根,有时会返回根数 ( 0
)。
现在,打印. 我对这个更持怀疑态度。显示自身不是方程式的“本机”属性。如果你这样做,你很快将不得不在你的方程类中处理与“方程”完全无关的问题:如何在文件中写入?二进制还是文本?我应该使用哪种编码?如何处理 I/O 错误?等等...
所以,如果我是你,我会推动关注点分离,只提供一个“访问器”方法来返回根——并从外部显示它们。由于这似乎很重要,因此我在此处保留了该访问器和solve
方法之间的分离(对于某些类型的方程可能是计算密集型的)。仅将实例变量self.answer
用作缓存(memoization)
这是一个完整的例子:
class Eq(object):
def __init__(self):
self.answer = None # this should be calles "roots", no?
def roots(self):
if self.answer is None:
self.solve()
return self.answer
class QuadEq(Eq):
def __init__(self, a, b, c):
Eq.__init__(self)
self.a = a
self.b = b
self.c = c
def solve(self):
self.answer = ("this", "that")
return 2
eq = QuadEq(1,2,3)
print(eq.roots())
请注意现在在程序中添加另一种方程来求解是多么容易......
class OtherEq(Eq):
def __init__(self, a, b, c):
Eq.__init__(self)
self.a = a
self.b = b
self.c = c
def solve(self):
self.answer = ( "it", )
return 1
...更重要的是,使用这种新方程的代码与前一个几乎相同:
eq = OtherEq(1,2,3)
print(eq.roots())