While everyone is saying what they want in Python :)

Martijn Faassen m.faassen at vet.uu.nl
Tue Feb 6 18:34:36 EST 2001


Jim Richardson <warlock at eskimo.com> wrote:
> On Sun, 04 Feb 2001 08:20:24 -0800, 
>  Daniel Klein, in the persona of <danielk at aracnet.com>,
>  brought forth the following words...:

>>On Sun, 04 Feb 2001 14:19:04 +0000, Jay O'Connor <joconnor at cybermesa.com>
>>
>>That's cos Smalltalk returns 'self' by default when a there is no explicit
>>return value. This can be done in Python if your 'set' methods return 'self'
>>instead of 'None'. For example:

> can someone explain to me what exactly "self" is for? I just don't get it.
> (I am trying to learn this language, but this puzzles me.) Every time I think I
> get it, I find proof otherwise :)

I'll add another answer to the list of answers given.

Let's first consider the case not using self at all. We have a class
that's just empty (you can see it as a dynamic structure or as a
type of dictionary; it is in fact a fancy dictionary):

class Record:
    pass

# let's make an initialization function
def record_init(record, name, street, city, country):
    record.name = name
    record.street = street
    record.city = city
    record.country = country

# let's make a function that prints the record
def record_print(record):
    print record.name, record.street, record.city, record.country

# and a function that can compare two records
def record_is_same(record, other_record):
    if (record.name == other_record.name and
        record.street == other_record.street and
        record.city == other_record.city and
        record.country = other_record.country):
        return 1
    else:
        return 0

You can imagine a whole host of functions that may do stuff with your
records.

Let's use them:

record = Record() # create a record
record_init(record, "Mr. Foo", "FooStreet 1", "Fooville", "Foogistan")
record_print(record)
# if record equal to itself?
if record_is_same(record, record):
    print "It's the same!"

Now let's write down the same, but using 'self' and methods instead.
Note that it's very much the same!

class Record:
    def __init__(self, name, street, city, country):
        self.name = name
        self.street = street
        self.city = city
        self.country = country

    def myprint(self):
        print self.name, self.street, self.city, self.country

    def is_same(self, other):
        if (self.name == other.name and
            self.street == other.street and
            self.city == other.city and
            self.country = other.country):
            return 1
        else:
            return 0

Let's use this:

record = Record("Bar", "44th Bar Street", "Bartown", "Baronia")
record.myprint()
record.is_same(record)

As you can see, the differences are minimal. We're using 'self' instead of
'record' (this is just a convention). We're using methods to the class
instead of functions. This makes it very easy make a slightly different
type of record later, which has a different print function, for instance,
but can still be used by the same code as nothing else is different.
That's a very powerful OO concept, called 'polymorphism'. Classes also
can inherit from each other, making polymorphism easier to accomplish
(as the methods inherited are automatically shared unless you define them
in some other way). These kind of things are somewhat harder to accomplish
by functions alone.

Another difference is that we use __init__ as a special method name; Python
knows to call this when we're constructing an instance of the class
(with Record(...)).

The 'self' is explicit as opposed to what's usual in C++ and Java because
it's clearer this way to see what's going on; it's always clear when
you're calling a method on a class instead of calling some function or
using a local variable.

I hope this helps.

Regards,

Martijn
-- 
History of the 20th Century: WW1, WW2, WW3?
No, WWW -- Could we be going in the right direction?



More information about the Python-list mailing list