1

I am a beginning python learner. Why is this code not printing 100?

class Pet(object):

    def __init__(self):
        self.name = ''
        self.age = 0

    def getName(self, newname):
        self.name = newname
        return self.name

    def getAge(self, aging):
        self.age += aging
        return self.age


polly = Pet()
polly.getAge(100)
print polly.getAge
5
  • 1
    Because you're not actually calling the function. Commented Oct 30, 2015 at 19:37
  • 3
    A function named getAge probably should not be modifying anything. Commented Oct 30, 2015 at 19:40
  • Thank you for the quick response but my intention was polly supposed to be outside of the class, can you please post a fix to where it should print 100 to the screen? Commented Oct 30, 2015 at 19:43
  • 1
    Stop downvoting this people... we were all beginners once and we all made mistakes like this (I certainly did, and so did most people I know). This is actually a decent beginner question since OP posted a concise working code snippet. Be welcoming to the new kid! Commented Oct 30, 2015 at 20:03
  • The world is beautiful place because of people like you... Thank you!! Commented Oct 31, 2015 at 17:49

4 Answers 4

5

Step through it.

polly = Pet()  # initialize a new Pet
polly.getAge(100)  # add 100 to polly.age
print polly.getAge   # print the getAge method bound to polly

Did you maybe mean to do

polly = Pet()
polly.getAge(100)
print polly.age 

Or:

polly = Pet()
print polly.getAge(100) 

?

No matter what, you should be nice and not mutate values with a getX method. It's definitely unexpected behavior.

Sign up to request clarification or add additional context in comments.

1 Comment

polly = Pet() print polly.getAge(100) #thank you this works
5

1) You meant print polly.getAge() instead of print polly.getAge.

2) However you then have a second issue (getAge() requires aging to be mandatory, which it totally shouldn't). You can kludge that with print polly.getAge(0), or fix it properly, see below.

Back to 1) The former actually calls the function/method (well it tries to call it, except for the issue of 2)) The latter is wrong, it only prints information about the actual function/method, but doesn't actually call it.

You can explore more by seeing that type(polly.getAge()) (or type(polly.getAge(0))) is an int, different to type(polly.getAge), which will be some type for function/method.

2) Your second issue here is getAge(...) is pretending to be a getter function but it also has a mandatory parameter aging and is implementing the aging, this is considered "method abuse" and violates separation of concerns, or at least don't name it getX which is really reserved for getters. Your alternatives are a) give it a default getAge(self, aging=0) (or use @property decorator), now it behaves like a getter when called getAge(). Or b) refactor out the two separate pieces of functionality into separate methods ("separation of concerns"):

class Pet(object):
    ...
    def getAge(self, aging):
        return self.age

    def doAging(self, aging):
        self.age += aging
        # Note that doAging() has no return value, and that is correct behavior (it's a method, not a getter)

In general that is a better and more maintainable design, we frown on "magical getters/setters" with side-effects, for tons of reasons (one of which is they f### up unit-testing). As you start adding more methods, you'll see why very quickly...

4 Comments

Which would itself fail because getAge takes a required argument.
@ppperry: right, I didn't see that aging was a mandatory parameter, I assumed OP would give it a default getAge(self, aging=0). This is "method abuse", since getAge is no longer a getter, it should be age(...) or doAging(...)
I don't appreciate the tactical downvoters... I wrote a valid answer and I didn't notice at first that aging was a mandatory parameter, since noone ever writes a getter with a mandatory parameter that changes the object.
@Kamaal if you got it to work, please mark an answer
3

Really you should have a method for setting and getting the age.

class Pet(object):

    def __init__(self):
        self.name = ''
        self.age = 0

    def getName(self, newname):
        self.name = newname
        return self.name

    def getAge(self):
        return self.age

    def setAge(self, newage):
        self.age = newage
        return None

polly = Pet()
polly.setAge(100)
print (polly.getAge())

2 Comments

I'd prefer to see setters returning None to match the style in the stdlib (mutators like list.sort, etc), but YMMV
Point taken, I have included your suggestion
0

Here is the modified code. I hope this will help you.

class Pet:

##    def __init__(self):
##        self.name = ''
##        self.age = 0

    def setAge(self, age):
        self.age = age
        #return self.age

    def getAge(self):
##        self.age = aging
##        return self.age
        print self.age


polly = Pet()
polly.setAge(100)
polly.getAge()
#print (polly.getAge)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.