0

I'm trying to understand the self keyword in python classes. Ergo I made up a simple class:

class Question(object):
    """A class for answering my OO questions about python.

       attributes: a_number"""

    def __init__():
        print "You've initialized a Question!"

    def myself_add(self, new_number):
        self.a_number += new_number

And in a __main__ function below the class definition I'm running the code

my_q = Question
print my_q
my_q.a_number = 12
print 'A number:',my_q.a_number
my_q.myself_add(3)
print 'A number:',my_q.a_number

The result I'm getting (including error) is

<class '__main__.Question'>
A number: 12
Traceback (most recent call last):
  File "question.py", line 21, in <module>
    my_q.myself_add(3)
TypeError: unbound method myself_add() must be called with Question instance as first argument (got int instance instead)

I'm trying to understand why the method myself_add is considered unbound. What does that mean? And why doesn't it know that I'm calling it on an instance of the Question class? Also, why doesn't my __init__ print happen?

wogsland
  • 9,106
  • 19
  • 57
  • 93

3 Answers3

1

In order to create an instance you need to write Question() not Question.

__init__ should take at least self argument

You may also want to initialize self.a_number in __init__ or put in into the class body, otherwise the call of myself_add will fail if you do not execute my_q.a_number = 12

Paweł Kordowski
  • 2,688
  • 1
  • 14
  • 21
1

The "self" argument can be anything, but is called self by convention.

It's passed in for you by python on default.

You can try running this simple code snippet to see what I mean:

class A(object):
    def __init__(self):
        pass
    def check(self, checked):
        print self is checked

and then from the command line:

a=A()
a.check(a)

You can take this further like this:

In [74]: b=A()

In [75]: a.check(b)
False

So here I've created two instances of A, one called a one called b. Only when comparing and instance of a's self to a itself is the statement true.

Hopefully that makes sense.

Specifically in your case, your class Question needs to be instantiated (Question()) and your __init__ needs an argument (self by convention).

On when a function is bound, you might find this answer helpful:

What is the difference between a function, an unbound method and a bound method? (but might be a bid advanced)

Community
  • 1
  • 1
James R
  • 4,571
  • 3
  • 30
  • 45
  • 1
    Great reference there, James. I'm used to languages where you have to syntactically differentiate class and instance methods, so that really cleared thing up a bit! – wogsland Mar 17 '17 at 16:41
1

First of all , when you initialize an instance of an class you use opening and closing parenthesis which calls the __init__ method by convention.

my_q = Question()

However, in your case your __init__ method is not bound to an object using self, so if you run as is it will give error,

    my_q = Question()
TypeError: __init__() takes no arguments (1 given)
>>> 

You need to initialize __init__ with self so that instance can make implicit call to the object.

def __init__(self):

Now , the program runs smoothly First print is the my_q object itself.

>>> 
You've initialized a Question!
<__main__.Question object at 0x028ED2F0>
A number: 12
A number: 15
Anil_M
  • 10,893
  • 6
  • 47
  • 74