Python面向对象的实现

时间:2012-09-19 21:48:43

标签: python

我在下面尝试这段代码,但想知道为什么它不起作用..

你能否告诉我这个问题,

code.py

class Example():


    def A1(self):
        return self.B1() + self.B2()


    def B1(self):
        return 4 * self.C1() 

    def B2(self):
        return 5

    def C1(self):
        return 2


def main():
    spreadsheet = Example()
    print spreadsheet.A1()

    spreadsheet.C1 = 3
    print spreadsheet.A1()

4 个答案:

答案 0 :(得分:4)

C1作为一种方法开始 - 你调用.A1(),调用.B1(),调用.C1(),返回2.到目前为止,非常好。

然后你.C1一个值(3) - 你调用.A1(),它调用.B1(),它试图调用.C1(),它会爆炸,因为值3不可调用

也许你想要像

这样的东西
class Spreadsheet(object):
    def __getattribute__(self, cell):
        val = object.__getattribute__(self, cell)
        return val(self) if callable(val) else val

def main():
    s = Spreadsheet()

    s.a1 = lambda self: self.b1 + self.b2
    s.b1 = lambda self: 4 * self.c1
    s.b2 = 5

    s.c1 = 2
    print s.a1  # => 13

    s.c1 = 3
    print s.a1  # => 17

答案 1 :(得分:2)

在您的班级中,变量C1只是一个包含实例方法的变量。将其设置为3会覆盖该函数。

例如:

def foo():
  print 4

foo = 12  # foo is now the number 12, not a function

你做了同样的事情:

spreadsheet.C1 = 3

C1 一个函数,但现在它是一个数字。你不能拨打电话。

答案 2 :(得分:1)

名称“C1”指的是方法(可调用对象)。但是然后你将“C1”属性赋给一个整数(不可调用),并破坏该方法。然后,当您使用self.C1()调用它时,它将不再起作用。

答案 3 :(得分:1)

你的意思是,如果你执行main,你会在打印电子表格时得到一个TypeError.A1()

这是因为你覆盖了实例变量C1。它被分配给一个函数,但是然后你将它重新分配给整数3.当它试图处理实例方法A1时,它最终会尝试调​​用self.C1()并找到一个整数,它不能被调用,并且应该是t后面有括号,所以它会正确抛出错误。

根据您想要发生的事情,您有几种选择。

  • 接受这是正常行为,不要覆盖实例程序。
  • 为C1定义一个setter,它将在该点返回错误或无声地执行任何操作。