What is "self"?

W

Wayne Sutton

OK, I'm a newbie...
I'm trying to learn Python & have had fun with it so far. But I'm having
trouble following the many code examples with the object "self." Can
someone explain this usage in plain english?

Thanks,
Wayne
 
R

Ron Adam

Wayne said:
OK, I'm a newbie...
I'm trying to learn Python & have had fun with it so far. But I'm having
trouble following the many code examples with the object "self." Can
someone explain this usage in plain english?

Thanks,
Wayne


I'll give it a try..

When you have a class definition:

class Person(object):
def set_name(self, name):
self.name = name

The method "set_name", has no idea what your class instance is going to
called at this point. But it will need to know when it's called. So
for now "self" is just a argument waiting to be assigned a reference
later just like any other function argument. You can actually call it
anything you want but "self" is sort of a tradition.

leader = Person()

This creates an instance of your class and stores a reference to it in
the name "leader". Now that that you have an instance with a name. You
can use your class method to do something.

leader.set_name("John")

When you call a method of an instance, Python translates it to...

leader.set_name(leader, "John")

So "self" in your method definition gets assigned a reference to
"leader". "self" can then be used to access the other values and
methods stored in your class instance. Or in this case store a value in
your class instance. Basically "self" becomes a reference to the class
instance it is in.

self.name = name

is the same as ...

leader.name = name

But we didn't know it was going to be called "leader" when we wrote the
class. So self is a convienent place holder.


I hope this helped.

Cheers,
Ron
 
S

Sam Pointon

self is the class instance that the bound function being called belongs
to. This example should illustrate a bit.


class Foo(object):
def __init__(self, value):
self.value = value # so the Foo instance now has an attribute,
value

def get_value(self):
return self.value # This gets the previously-set value
attribute of the Foo instance

bar = Foo(42)
baz = Foo('101010')

print bar.get_value() #Note that the self argument is implicit since
this is a bound method.
print
print baz.get_value()

The output is (or should be, as this is untested):
42

101010
 
M

marduk

OK, I'm a newbie...
I'm trying to learn Python & have had fun with it so far. But I'm having
trouble following the many code examples with the object "self." Can
someone explain this usage in plain english?

"self" references the object itself. It's usually also called "this" on
other languages (C++ & Java I believe). In Python, when you define a
class method, the reference to the object is passed explicitly rather
than implicitly.

Also, the name "self" is used by convention. You could use any name if
you wanted, but if you want other people to understand your code then
use "self".

Is that plain English enough?
 
J

James Stroud

I'm sure there are answers to this out there, but I'm typing this one up so I
can show it to people that I try to teach this language. They consistently
get hung up on what self is. So here is my try:

==

Self is one of those python concepts that new python programmers have a little
difficulty with. It refers to the instance of the class that is calling the
method. That's confusing, so let's do an example.

Say you have a class called Thing

class Thing:
def __init__(self, aval):
self.value = aval
def doit(self, another_val):
print "Time 'till end of world:", (self.value + another_val)


You can instatiate the thing class

athing = Thing(1)

The object referenced by the name "athing" lives in your computers memory
somewhere. The name "athing" is how we reference, or talk about, that object.
Above, "doit" is a member function of the Thing class. How can we call doit?

athing.doit(5)

What happened here? Why did we need self in the definition of doit when we
didn't obviously pass something that we could construe as self? Well, we did
pass something we could construe as self, it was "athing". How is this? Well,

athing.doit(5)

is equivalent to (and shorthand for)

Thing.doit(athing, 5)

Here is a picture of what this did:

def doit(self, another_val)
^ ^
athing 5

print "Time 'till end of world:", (self.value + another_val)
^ ^
athing.value 5


This complies with the signature of the "Thing.doit" member function. The
compiler turned the shorthand "athing.doit(5)" into "Thing.doit(athing, 5)"
for us, saving us a little typing in the process and making our code easier
to read.

So, when we talk use self as a name in class member functions, we are actually
referencing the instance that was passed to the member function. So for this
example "athing" and "self" reference the same object. If an instance called
another_thing was passed, then another_thing and self would refence the same
object:

another_thing = Thing()
Thing.doit(another_thing, 5) # same as another_thing.doit(5)

==

OK, I'm a newbie...
I'm trying to learn Python & have had fun with it so far. But I'm having
trouble following the many code examples with the object "self." Can
someone explain this usage in plain english?

Thanks,
Wayne

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
E

Erik Max Francis

Ron said:
When you call a method of an instance, Python translates it to...

leader.set_name(leader, "John")

It actually translates it to

Person.set_name(leader, "John")
 
R

Roy Smith

Ron Adam said:
You can actually call it anything you want but "self" is sort of a
tradition.

That's true, but I think needs to be said a bit more emphatically. There's
no reason to call it anything other than "self" and a newcomer to the
language would be well advised to not try and be creative here. Using
"self" is virtually universal, and calling it anything else will just lead
to confusion by other people who have to read your code.
 
R

Rick Wotnaz

That's true, but I think needs to be said a bit more
emphatically. There's no reason to call it anything other than
"self" and a newcomer to the language would be well advised to
not try and be creative here. Using "self" is virtually
universal, and calling it anything else will just lead to
confusion by other people who have to read your code.

I've long thought that Guido missed an opportunity by not choosing
to use 'i' as the instance identifier, and making it a reserved
word. For one thing, it would resonate with the personal pronoun
'I', and so carry essentially the same meaning as 'self'. It could
also be understood as an initialism for 'instance'. And, because it
is shorter, the number of objections to its existence *might* have
been smaller than seems to be the case with 'self' as the
convention.

And as a side benefit, it would make it impossible to use as a loop
index a language feature that would be a huge selling point among a
lot of experienced programmers.
 
J

Jeff Schwab

Rick said:
I've long thought that Guido missed an opportunity by not choosing
to use 'i' as the instance identifier, and making it a reserved
word. For one thing, it would resonate with the personal pronoun
'I', and so carry essentially the same meaning as 'self'. It could
also be understood as an initialism for 'instance'. And, because it
is shorter, the number of objections to its existence *might* have
been smaller than seems to be the case with 'self' as the
convention.

And as a side benefit, it would make it impossible to use as a loop
index a language feature that would be a huge selling point among a
lot of experienced programmers.

And an annoyance to others.
 
S

Sion Arrowsmith

Rick Wotnaz said:
I've long thought that Guido missed an opportunity by not choosing
to use 'i' as the instance identifier, and making it a reserved
word. For one thing, it would resonate with the personal pronoun
'I', and so carry essentially the same meaning as 'self'. It could
also be understood as an initialism for 'instance'. And, because it
is shorter, the number of objections to its existence *might* have
been smaller than seems to be the case with 'self' as the
convention.

My first serious forays into Python, where no-one else was expected
to be maintaining the code, used 'I' instead of 'self' -- it's
shorter, stands out better, and 'I.do_something()' reads more like
English than 'self.do_something()' (unless, I suppose, you're
thinking in terms of message passing). Then I started working on
code which other people might need to look at, and got an editor
whose Python syntax highlighting pretended that 'self' was a
reserved word, and now all my old code looks odd. (But still
perfectly readable -- this is Python after all.)
 
T

Terry Hancock

I've long thought that Guido missed an opportunity by not choosing
to use 'i' as the instance identifier, and making it a reserved
word. For one thing, it would resonate with the personal pronoun
'I', and so carry essentially the same meaning as 'self'. It could
also be understood as an initialism for 'instance'. And, because it
is shorter, the number of objections to its existence *might* have
been smaller than seems to be the case with 'self' as the
convention.

And as a side benefit, it would make it impossible to use as a loop
index a language feature that would be a huge selling point among a
lot of experienced programmers.

How exactly is that? Anybody who uses "i" as a variable name for
anything other than an innermost loop index is a sick and twisted
code sadist.

You'd prefer what? "count" or "kount" or "i_am_an_innermost_loop_index_counter".
I mean "explicit is better than implicit", right?

Maybe Fortran warped my brain, but I just don't see the benefit here.
 
R

Rick Wotnaz

How exactly is that? Anybody who uses "i" as a variable name
for anything other than an innermost loop index is a sick and
twisted code sadist.

You'd prefer what? "count" or "kount" or
"i_am_an_innermost_loop_index_counter". I mean "explicit is
better than implicit", right?

Maybe Fortran warped my brain, but I just don't see the benefit
here. --

Oh, 'ix' would be fine. Single-letter loop counters are also semi-
fine if that is in fact their only use. It too-frequently happens
that at some point the handy 'i' identifier is used outside the
loop (for another placeholder), and its value is tromped by an
intervening loop. Not terribly difficult to discover, but then
what? When you're maintaining code, even a two-character index is a
*lot* easier to find in source code and replace as needed.
 
P

Peter

Not realy.
MUCH better then trying to make it refer to "i" as in "me", but still.
Humm... maybe. But would reap the fact that i does not have the same
exact meaning of self.
With the word self, it is possable to change a feature of yourSELF, but
try saying you changed a feature of "yourI", some internal logic in the
programmers brain is going to go off, and if the programmer is tired and
trying to finish something up but has that kind of internal confusion,
as suttle as it may be, he will get burnt out and have to wait intill
the next day.
You think thats a good thing? o.0.
I agree that sometimes you need to name your loop variables well, but
sometimes you only need a simple, temp loop variable.

I would expect such an aprouch to be more likely to be found in intercal
(http://www.catb.org/~esr/intercal/), rather then in Python.
How exactly is that? Anybody who uses "i" as a variable name for
anything other than an innermost loop index is a sick and twisted
code sadist.
Agreed, though to say "code sadist" is a little hard don't ya think? ;)
You'd prefer what? "count" or "kount" or "i_am_an_innermost_loop_index_counter".
I mean "explicit is better than implicit", right?


Maybe Fortran warped my brain, but I just don't see the benefit here.
Me ither.

I am no english professor, but isn't the word "i" usualy pointed at
something you will, have, can, or can't do in english?
"me" or "self" or "this" or "my" or "cls" or "inst" are refering to just
the object, nothing more, nothing less (except for "my" which is like
referring to "something i own") and are much more human-comprehendable.
IMHO.

Peter
 
T

Terry Hancock

Agreed, though to say "code sadist" is a little hard don't ya think? ;)

I don't know, I thought it quite poetic. ;-)
Me ither.

I am no english professor, but isn't the word "i" usualy pointed at
something you will, have, can, or can't do in english?
"me" or "self" or "this" or "my" or "cls" or "inst" are refering to just
the object, nothing more, nothing less (except for "my" which is like
referring to "something i own") and are much more human-comprehendable.
IMHO.

Whoa, you totally lost me there, dude.

;-)
 
T

Terry Hancock

Oh, 'ix' would be fine. Single-letter loop counters are also semi-
fine if that is in fact their only use. It too-frequently happens
that at some point the handy 'i' identifier is used outside the
loop (for another placeholder), and its value is tromped by an
intervening loop. Not terribly difficult to discover, but then
what? When you're maintaining code, even a two-character index is a
*lot* easier to find in source code and replace as needed.

Sorry, but if you have to grep for it, your loop is TOO DARNED LARGE,
USE A FUNCTION CALL!
 
R

Ron Adam

Erik said:
It actually translates it to

Person.set_name(leader, "John")

I thought that I might have missed something there.

Is there a paper on how python accesses and stores instance data and
methods? I googled but couldn't find anything that addressed this
particular question.
.... def x(self):
.... print 'x'
....<bound method a.x of <__main__.a object at 0x009D1890>>

So what exactly is a bound method object? Does it possibly translates
to something like the following?

def x(*args, **kwds):
self = ?
return __class__.self(self, *args, **kwds)

Cheers,
Ron
 
M

Michael Spencer

Ron said:
I thought that I might have missed something there.

Is there a paper on how python accesses and stores instance data and
methods? I googled but couldn't find anything that addressed this
particular question.

... def x(self):
... print 'x'
...
<bound method a.x of <__main__.a object at 0x009D1890>>

So what exactly is a bound method object? Does it possibly translates
to something like the following?

def x(*args, **kwds):
self = ?
return __class__.self(self, *args, **kwds)

Cheers,
Ron

All is explained at:
http://users.rcn.com/python/download/Descriptor.htm#functions-and-methods
and further at:
http://www.python.org/pycon/2005/papers/36/pyc05_bla_dp.pdf

"For objects, the machinery is in object.__getattribute__ which transforms b.x
into type(b).__dict__['x'].__get__(b, type(b))."

What follows is my interpretation - hope it's correct:

# what exactly is a bound method object?
# Illustrate b.f => type(b).__dict__['x'].__get__(b, type(b))
... def f(self, x):
... return x or 42
...
>>> b = B()
>>> type(b).__dict__['f']
said:
>>> _.__get__(b, type(b)) # invoke the descriptor protocol
# to make a bound method

You don't have to use object.__getattribute__ to get a bound method. Nor does
the function have to be in the class dictionary. You can just call any function
descriptor yourself:
... return self.f(y)
...
Looked at this way, function.__get__ just does partial function application (aka
currying).
... return x+y
... 43


Michael
 
R

Ron Adam

Michael said:
All is explained at:
http://users.rcn.com/python/download/Descriptor.htm#functions-and-methods
and further at:
http://www.python.org/pycon/2005/papers/36/pyc05_bla_dp.pdf

"For objects, the machinery is in object.__getattribute__ which
transforms b.x into type(b).__dict__['x'].__get__(b, type(b))."

What follows is my interpretation - hope it's correct:

# what exactly is a bound method object?
# Illustrate b.f => type(b).__dict__['x'].__get__(b, type(b))
... def f(self, x):
... return x or 42
...
b = B()
type(b).__dict__['f']
_.__get__(b, type(b)) # invoke the descriptor protocol
# to make a bound method

This still seems not quite right to me... Or more likely seems to be
missing something still.

(But it could be this migraine I've had the last couple of days
preventing me from being able to concentrate on things with more than a
few levels of complexity.)

Playing around with the shell a bit gives the impression that calling a
method in a instance gives the following (approximate) result...

try:
leader.__dict__["set_name"]("John")
except:
type(leader).__dict__["set_name"].__get__(leader, "John")
# which results in...
# Person.set_name(leader, "John")
except:
raise( AttributeError,
"%s object has no attribute %s" \
% (leader, "set_name") )


Of course this wouldn't use the object names directly... I guess I'll
need to look in the C object code to see exactly how it works. But the
links you gave help.

Thanks,
Ron
 
D

Diez B. Roggisch

This still seems not quite right to me... Or more likely seems to be
missing something still.

(But it could be this migraine I've had the last couple of days
preventing me from being able to concentrate on things with more than a
few levels of complexity.)

Playing around with the shell a bit gives the impression that calling a
method in a instance gives the following (approximate) result...

try:
leader.__dict__["set_name"]("John")
except:
type(leader).__dict__["set_name"].__get__(leader, "John")
# which results in...
# Person.set_name(leader, "John")
except:
raise( AttributeError,
"%s object has no attribute %s" \
% (leader, "set_name") )


Of course this wouldn't use the object names directly... I guess I'll
need to look in the C object code to see exactly how it works. But the
links you gave help.

I guess you mean to indent the whole part after the first except and put
a try beforehand?

Apart from that you seem to be right - there can very well be values in
the class dict that don't follow the descriptor-protocol. However my
playing around with this stuff indicates that the creation of bound
methods relies on the method being wrapped in a descriptor - otherwise,
you get the notorious TypeError

set_name() takes exactly 1 argument (0 given)

as the binding doesn't occur.

Regards,

Diez
 
R

Ron Adam

Diez said:
This still seems not quite right to me... Or more likely seems to be
missing something still.

(But it could be this migraine I've had the last couple of days
preventing me from being able to concentrate on things with more than
a few levels of complexity.)

Playing around with the shell a bit gives the impression that calling
a method in a instance gives the following (approximate) result...

try:
leader.__dict__["set_name"]("John")
except:
type(leader).__dict__["set_name"].__get__(leader, "John")
# which results in...
# Person.set_name(leader, "John")
except:
raise( AttributeError,
"%s object has no attribute %s" \
% (leader, "set_name") )


Of course this wouldn't use the object names directly... I guess I'll
need to look in the C object code to see exactly how it works. But
the links you gave help.


I guess you mean to indent the whole part after the first except and put
a try beforehand?

Yes, I did. I'm not sure why I left out the try.

try:
leader.__dict__["set_name"]("John")
except:
try:
type(leader).__dict__["set_name"].__get__(leader, "John")
# which results in...
# Person.set_name(leader, "John")
except:
raise( AttributeError,
"%s object has no attribute %s" \
% (leader, "set_name") )
Apart from that you seem to be right - there can very well be values in
the class dict that don't follow the descriptor-protocol. However my
playing around with this stuff indicates that the creation of bound
methods relies on the method being wrapped in a descriptor - otherwise,
you get the notorious TypeError
>
set_name() takes exactly 1 argument (0 given)

as the binding doesn't occur.

Regards,

Diez

What I've noticed is you can block the visibility of a class attribute,
which include methods, by inserting an object in the instance with the
same name.

Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information..... def b(self, value):
.... print value
........ print "%r" % value
....
So the underlying mechanism for calling methods doesn't kick in until
*after* an attempt to get an attribute of the same name in the instance.
.... print list(value)
....['h', 'e', 'l', 'l', 'o']

The attribute aa.boo is not there, so call boo.__get__() in class a.


Cheers,
Ron
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,264
Messages
2,571,323
Members
48,006
Latest member
TerranceCo

Latest Threads

Top