Daniel
Daniel

Reputation: 1582

Understanding "self" in Python

I saw this example from udacity.com :

def say_hi():
    return 'hi!'

i = 789

class MyClass(object):

    i = 5

    def prepare(self):
        i = 10
        self.i = 123
        print i

    def say_hi(self):
        return 'Hi there!'

    def say_something(self):
        print say_hi()

    def say_something_else(self):
        print self.say_hi()

output:

>>> print say_hi()
hi!
>>> print i
789
>>> a = MyClass()
>>> a.say_something()
hi!
>>> a.say_something_else()
Hi there!
>>> print a.i
5
>>> a.prepare()
10
>>> print i
789
>>> print a.i
123

I understand everything, except why a.say_something() equals hi! and not Hi there!. That is strange for me, because it calls say_something() which is inside the class when it calls say_hi() after that. Guess I missed something important..

Upvotes: 0

Views: 3049

Answers (6)

TankorSmash
TankorSmash

Reputation: 12747

It's calling say_hi from the global scope, rather than the class scope because, within the class scope, there's no such function as say_hi, only self.say_hi

Maybe this will help:

name = 'John'
class Person()

    def __init__(self)
      name = 'Abraham'

    def printName(self)
      print name

>>> pers  = Person()
>>> pers.printName()
   'John'  # uses global name, rather than Abraham, 
           # because Abe is not a class instance variable.

Upvotes: 0

moooeeeep
moooeeeep

Reputation: 32512

Consider the following code:

class X:
  def __init__(self, name):
    self.name = name
  def bound_method(self):
    print "I'm bound to", self.name
  @staticmethod
  def unbound_method():
    print "I have no self!"

x = X("Peter")
x.bound_method()   # prints: I'm bound to Peter
x.unbound_method() # prints: I have no self!

Class members and member functions in Python are variables and callables that are bound to an object of the class. These bound methods receive the object they are called with as their first call parameter, that is usually named self. Referring to bound methods and variables needs to be done explicitly, as in x.bound_method(). The object x is thereby turned into the first function argument self. If you want to access its members, you need to query self inside the function.

There are also class methods in Python. That is functions that are not bound to a specific instantiation, but are static to the class, see unbound_method() for an example.

Upvotes: 1

Steven Almeroth
Steven Almeroth

Reputation: 8202

Maybe this example will make more sense:

def global_scope_hi():
    return 'hi!'

class MyClass(object):

    def class_scope_hi(object_reference):
        return 'Hi there!'

    def say_something(object_reference):
        print global_scope_hi()

    def say_something_else(object_reference):
        print object_reference.class_scope_hi()

a = MyClass()
a.say_something()
a.say_something_else()

>>> hi!
>>> Hi there!

Upvotes: 0

Farnabaz
Farnabaz

Reputation: 4066

in python to call inner class method you should write self. before method name, self. means that search class for this method but you don't use self when you call say_hi() in say_something method and this cause to call say_hi function that declared outside of class.
write this to solve problem.

def say_something(self):
    print self.say_hi()

Upvotes: 0

null
null

Reputation: 11869

It's because a.say_something() doesn't call class method (it doesn't have self. part so it calls global function).

Upvotes: 0

Sven Marnach
Sven Marnach

Reputation: 601609

Class scopes aren't considered when looking up a name in enclosing scopes. You should always qualify with self. to get a name from the class scope.

See The scope of names defined in class block doesn't extend to the methods' blocks. Why is that? for a more detailed discussion of this behaviour.

Upvotes: 5

Related Questions