[Tutor] Understanding Classes
spir
denis.spir at gmail.com
Mon Jan 20 22:20:53 CET 2014
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
More information about the Tutor
mailing list