简体   繁体   中英

Python object oriented implementation

Im trying this piece of code below but wondering why its not working..

Can you please let me know wht is the problem,

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()

C1 starts out as a method - you call .A1(), which calls .B1(), which calls .C1(), which returns 2. So far, so good.

You then make .C1 a value (3) - you call .A1(), which calls .B1(), which tries to call .C1(), which blows up because the value 3 is not callable .

Maybe you want something like

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

In your class, the variable C1 was just a variable that held an instance method. Setting it equal to 3 overrides the function.

For example:

def foo():
  print 4

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

You did the same thing:

spreadsheet.C1 = 3

C1 was a function, but now it's a number. You can't call a number.

The name "C1" refers to a method (a callable object). But then you assign "C1" attribute to an integer (not callable), and clobber the method. Then when you call it with self.C1() it won't work anymore.

You mean that if you execute main you get a TypeError when it gets to print spreadsheet.A1()

It is because you overwrite the instance variable C1. It was assigned to a function, but then you reassign it to the integer 3. When it tries to process the instance method A1 it eventually tries to call self.C1() and finds an integer, which can't be called and shouldn't have the parenthesis after it, so it properly throws an error.

Depending on what you want to happen you have several options.

  • Accept that this is normal behavior and don't overwrite instance procedures.
  • Define a setter for C1 that would either return an error at that point or silently do nothing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM