On 01/19/2014 10:59 PM, Christian Alexander wrote:
Hello Tutorians,

Looked all over the net for class tutorials
Unable to understand the "self" argument
Attempting to visual classes

I have searched high and low, for easy to follow tutorials regarding
classes.  Although I grok the general concept of classes,  I am unable to
visually understand what exactly "self" does, or why it is even necessary.
  It seems very "magic" to me.  Also I am having the most difficult with the
"__init__()" method in classes, and why that is also required.  Keep in
mind that I am a visual person (maybe I should have been a graphic
designer), therefore most programming concepts flow irritatingly slow for
me.

Imagine that for an app you had to define 2 persons p1 & p2 (maybe game characters for instance). In an imaginary programming language, a definition of p1 could look like this:

    p1 = {name="Maria", age=33}     # no good python code

This would be a composite piece of data, made of 2 fields (attributes, properties...). In python there is no such generic type Object or Composite to which such data as p1 could belong. You must define a custom type (class) for them, eg:

    class Person: pass

Now, you can have p1 of type Person, which is written as if you would call the type Person, like a func, to make a new person (this is close to what happens):

    p1 = Person()

Then, one can define fields on it:

    p1.name = "Maria"
    p1.age = 33
    print(p1.name, p1.age)

We could do the same thing for p2:

    p2 = Person()
    p2.name = "paulo"
    p2.age = 22
    print(p2.name, p2.age)

Now, say persons are supposed to do things, and all can do the same things. To define something all persons can do, you would define it on their class (this is the second purpose of a class), eg:

    class Person:
        def salute (self):
            print ("Hello, my name is " + self.name +
                " and I am " + str(self.age) " years old.")

As you can see, this method uses the attributes 'name' & 'age' we manually defined on both p1 & p2. Then, how does the method, which is defined on the type, not on individual objects, know where to find these attributes? You are right to say there is some magic at play here. Let us use the method first, before explaining:

    p1.salute()
    p2.salute()

[Copy-paste & run all this code.] On the first call, we ask the method 'salute' to operate on p1, and it writes p1's name & age. Same for p2. Inside the method, the attributes are searched on the weird param called 'self'. This is just what happens: when calling a method, the object on which it operates is assigned to the parameter self. 'self' is just a name for the-object-on-which-this-method-operates-now. When it operates on p1, self is p1, thus attributes are searched on p1; same for p2. We need some placeholder because the method is defined on the type and works for any object of this type (any "instance"). [We can define a method on p1 which works on p1 only. Maybe try it.]

Finally, if we define a whole range of persons that way, it is annoying to set all attributes manually. We could define a method, say 'def_attrs', to be called at startup. But python has a specially dedicated method for that, which we don't even need to call explicitely, named '__init__'. We will use it to set person attributes:

    class Person:
        def __init__ (self, name, age):
            self.name = name
            self.age  = age
        def salute (self):
            print ("Hello, my name is " + self.name +
                " and I am " + str(self.age) " years old.")

(yes, init methods typically are as stupid as this; too bad python does not do the mechanical job automagically) And this is used like this:

    p1 = Person("maria", 33)    # no need to call __init__ explicitely
    p1.salute()
    p2 = Person("paulo", 22)    # ditto
    p2.salute()

denis
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to