Re: [Tutor] Understanding Classes

2014-01-21 Thread eryksun
On Tue, Jan 21, 2014 at 7:18 AM, Steven D'Aprano  wrote:
> The same applies to methods, with just one additional bit of magic: when
> you call a method like this:
>
>  instance.method(a, b, c)  # say
>
> Python turns it into a function call:
>
>  method(instance, a, b, c)
>
> [For advanced readers: to be precise, Python uses what is technically
> known as an *unbound method*, which it gets by looking inside the class
> of `instance`. To be even more precise, in Python 3, it no longer uses
> unbound methods but just regular functions. But the basic concept is
> the same.]

You're using 2.x but didn't subclass `object`. Old-style classes
behave differently in many cases, starting with the most basic
difference:

>>> type(my_car)


If you're targeting both 2.x and 3.x, remember to subclass `object` explicitly.

A minor correction about methods: it's a "bound" method:

>>> my_car.start_engine.__self__ is my_car
True

The wrapped function is `__func__`:

>>> type(my_car.start_engine.__func__)

>>> my_car.start_engine.__func__.__name__
'start_engine'
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Understanding Classes

2014-01-21 Thread Steven D'Aprano
On Sun, Jan 19, 2014 at 04:59:58PM -0500, Christian Alexander wrote:
> Hello Tutorians,
> 
> Looked all over the net for class tutorials
> Unable to understand the "self" argument
> Attempting to visual classes

Let me explain classes by analogy. Classes are best as representing 
things, that is, nouns, whether abstract nouns like numbers, or concrete 
nouns like cars. So let's work through an example.

Suppose I have a class Car. You might think of the class as a factory 
which creates cars. We call that factory a class, and the individual 
cars built by the factory "instances". (This analogy doesn't go far 
enough: there is a lot more to the relationship between instances and 
their class, but for now we'll start with this slightly inaccurate 
picture and then improve it later on.)

So the first thing that we do is we need to decide what sort of car the 
factory will produce. I don't mean the brand name and model, I mean, 
what does it do? What parts does it need? Two doors or four? So let's 
make a basic car that does just two things: it starts the engine, and 
stops the engine:

class Car:
def start_engine(self):
if self.gear not in ('Park', 'Neutral'):
raise RuntimeError('cannot start engine')
self.engine.start()

def stop_engine(self):
self.engine.stop()


Not a very interesting car, but all things must start somewhere. Now, 
lets look at those methods, `start_engine` and `stop_engine`. They take 
a single argument, `self`. What does self represent? It represents the 
individual car you wish to operate. You might end up with fifty cars:

car1 = Car()  # create a new car instance
car2 = Car()
car3 = Car()
...

Every one of those cars shares access to the same `start_engine` method. 
So when you call the method:

car23.start_engine()

how does the method know to start car23's engine, instead of car42 or 
car18? It knows because Python takes the bit before the dot (`car23`), 
and automatically passes it to the method as the `self` argument.

Confused? Let's make a brief side-track, and talk about functions. 
Here's a function:

def greet(name, greeting):
print greeting, name

If I call that function:

greet("Fred", "Greetings and salutations")
=> prints "Greetings and salutations Fred"

Python takes the first value, "Fred", and assigns it to the argument 
`name`, the second value "Greetings and salutations" and assigns it to 
the argument `greeting`. Then the function can access them as local 
variables inside the function.

The same applies to methods, with just one additional bit of magic: when 
you call a method like this:

 instance.method(a, b, c)  # say

Python turns it into a function call:

 method(instance, a, b, c)

[For advanced readers: to be precise, Python uses what is technically 
known as an *unbound method*, which it gets by looking inside the class 
of `instance`. To be even more precise, in Python 3, it no longer uses 
unbound methods but just regular functions. But the basic concept is 
the same.]

So, back to our car: we've got a car that has two methods, which 
controls the *behaviour* of the car, but they won't do anything except 
raise an exception, because the car doesn't have any *state*. It has no 
engine to turn on or off, and it has no memory of what gear it is in. So 
let's fix that.

Every individual car needs its own engine, and each car needs to 
remember it's own gear. The obvious time to add the engine is when we 
create the car. Python creates the car when you call the class name as 
if it were a function: 

my_car = Car()  # Python creates the car instance

Now of course, Python doesn't know what cars are supposed to include, so 
it just does the bare minimum, which basically is just to allocate a 
small amount of memory for the instance and a few other bits of 
behind-the-scenes book-keeping. The rest is up to you, and that's what 
the __init__ method is for. So we give the car an engine when we create 
the car, and set the gear at the same time:


class Car:
def __init__(self):
self.engine = Engine()
self.gear = "Neutral"

def start_engine(self):
if self.gear not in ('Park', 'Neutral'):
raise RuntimeError('cannot start engine')
self.engine.start()

def stop_engine(self):
self.engine.stop()



Of course, somebody has to write the Engine class too, but I can't be 
expected to do everything. Let's just pretend it already exists. Now you 
have a class which defines cars. When you call:

my_car = Car()

Python automatically calls the __init__ method with the newly created 
car instance as `self`. The __init__ method then runs, giving the car an 
engine, and setting the gear to neutral. Now, you should be able to 
start and stop the car:

my_car.start()
my_car.stop()


and provided the engine class knows how to start and stop, so will the 
car. So, in conclusion:

- the point of the `__init__` method is that Python automatically calls 
  that method whe

Re: [Tutor] Understanding Classes

2014-01-21 Thread Steven D'Aprano
On Mon, Jan 20, 2014 at 09:33:29AM +, Alan Gauld wrote:

> >However, I understand that classes are
> >parallel to that of a blueprint,
> 
> Yes, they define what the objects will look like, what data and what 
> methods they contain. But to use those objects you have to instantiate 
> them and its there that the usage varies slightly from the built in types:
> 
> For built in string type objects you do this
> 
> mystring = 'a new string object'
> 
> But if String were a user defined class you'd need to do this:
> 
> mystring = String('a user defined string object')

Just to be clear here, the difference is a simple matter of syntax. 
Because strings are so common in programming, Python gives you special 
syntax for creating strings. When you have code like this:

'a new string object'

Python still has to create a string object, exactly the same as with a 
custom class. The only difference is that creating strings is handled 
automatically, by the Python interpreter, rather than by you having to 
create your own String class. (Of course you can create a string class 
if you so wish.)


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


Re: [Tutor] Understanding Classes

2014-01-21 Thread Alan Gauld

On 21/01/14 04:20, Christian Alexander wrote:


 class Person:
 def __init__ (self, name, age):# is self just a
placeholder for  an arbitrary object?


Yes. If you create say 4 persons, John, Paul, Ringo and George.
When you call any method on those people objects the same code
in the Person class will get executed. So that method code needs some 
way to know which object is being manipulated. That's all that self is, 
a reference to the object currently being worked on.



How does __init__ actually work?


__init__() is actually just an ordinary metjod like any other.
There is no magic in the method itself. It is a function that takes in 
arhguments (self, name, age in this case) and processes them (stores 
them in the self object).


The magic happens when the Class is instantiated.
So if we create a person object like this:

paul = Person("Paul", 71)

Python first creates a new empty object in memory then passes that 
object to Person.__init() with the arguments (paul, "Paul", 71).
The end result is an instance called paul pre-populated by the arguments 
that we passed to Person.


We can do that manually by not defining __init__()

class Person2:
   def setData(self, name, age):
   self.name = name
   self.age = age

paul = Person2()   # get a new empty Person2 object
paul.setData("Paul", 71)   # do the equivalent of __init__

print (paul.Name, paul.age)



self.name  = name # why
assign name to self.name  variable?


Remember that name is the input parameter to the method.
Just like any other function the input parameters are just
temporary variables that get thrown away at the end of
the function. We want to store those values in our new
instance. So we assign them to a data attribute of the
new object(self) for storage so that we can access them
in the future. For example the salute() method accesses
the self.name attribute. It can only use that if it has
been stored previously.

We can add attributes to an object at any time in Python.
For instance, using our paul example above we can do this:

paul.instrument = "bass"

and later print paul.instrument.

The equivalent of doing that inside a method is to use self.
So we could have another method in Person like this:

class Person:
   def __init__(self, name, age):
   def salute(self):
   def joinBand(self, instrument):
   self.instrument = instrument

and we can call that method as before

paul = Person("Paul", 71)
paul.joinBand("bass")

So setting attributes can be done anywhere and from
any method it's not special to init. But because init
gets called automatically when we first create the
object it's convenient to be able to set the initial
values at the same time as we create the object.

Is that helping?

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos

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


Re: [Tutor] Understanding Classes

2014-01-21 Thread Christian Alexander
Alan,

The concept and purpose of classes is starting to sink in a little bit, but
I still haven't had my "Ah-ha" moment yet.  I just can't seem to visualize
the execution of classes, nor am I able to explain to myself how it
actually works.   For example:


class Person:
def __init__ (self, name, age):# is self just a placeholder
for  an arbitrary object?  How does __init__ actually work?
self.name = name # why assign name to
self.name variable?
self.age  = age   # same as previous
def salute (self): # again with the
self
print ("Hello, my name is " + self.name +
" and I am " + str(self.age) " years old.")


On Mon, Jan 20, 2014 at 4:20 PM, spir  wrote:

> 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.o

Re: [Tutor] Understanding Classes

2014-01-21 Thread spir

On 01/21/2014 05:20 AM, Christian Alexander wrote:

Alan,

The concept and purpose of classes is starting to sink in a little bit, but
I still haven't had my "Ah-ha" moment yet.  I just can't seem to visualize
the execution of classes, nor am I able to explain to myself how it
actually works.   For example:


 class Person:
 def __init__ (self, name, age):# is self just a placeholder
for  an arbitrary object?  How does __init__ actually work?
 self.name = name # why assign name to
self.name variable?
 self.age  = age   # same as previous
 def salute (self): # again with the
self
 print ("Hello, my name is " + self.name +
 " and I am " + str(self.age) + " years old.")


[PLease avoid top-posting, and quote only the parts of the post you actually 
reply to.]


Yes, self is just a placeholder, as I said in the post you reply to. (I used the 
same word.) It is a placeholder for *whatever object it operates on, now*. If 
you call a Person methon on 'x', then x is assigned to self.


We assign name & age tp self, meaning to x, because a person is defined as a 
composite piece of data {name, age}. Read again the very start of my previous 
post, where I wrote the definition of p1, directly, in an imaginary language:


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

This is a programming of a person, as we need. This means, for this application, 
we need a person to be defined by these 2 relevant properties, both of them, and 
nothing more.


__init__ works as if we had programmed that way:

===
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.")

p1 = Person()
p1.init("Maria", 33)
p1.salute()


except that we don't need to call it. Do you understand the principle of (1) 
defining a function with potential input variables (2) executing it on actual 
input variables? In python the "potential input variables" are called 
"parameters", while "actual input variables" are called "arguments".


There is a similar relation between a class and objects of that class. A class 
defined potential objects, with potential attributes (here name & age); 
"instances" are actual objects of that class with actual attributes.


For the matter, I don't think your difficulties with these notions are related 
to you beeing a visual thinkers: I am, too, and strongly so (and after all, the 
notion of type is firstly visual: think at naive species).


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


Re: [Tutor] Understanding Classes

2014-01-20 Thread spir

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


Re: [Tutor] Understanding Classes

2014-01-20 Thread David
On 20 January 2014 20:33, Alan Gauld  wrote:
> On 20/01/14 00:55, Christian Alexander wrote:
>>
>> I would first like to state two things, those being that I am a horrible
>> writer as well as explaining things, but Ill try my absolute best.
>>   Everything python is an object.  Strings, integers, lists, so on and
>> so forth.  In regards to classes and their relativity towards objects, I
>> am at complete standstill.
>
> For built in string type objects you do this
>
> mystring = 'a new string object'
>
> But if String were a user defined class you'd need to do this:
>
> mystring = String('a user defined string object')
>
> ie. you'd 'call' the class name with the data arguments needed.
> In fact in Python you can explicitly call str() if you really
> want to, missing it out is a convenience.
>
> After that initial object creation you would use mystring identically
> regardless of whether it was user defined or built in. So we can call
> methods of the class using the instance like:
>
> mystring.upper()
> mystring.split()

And Christian you can experiment with Alan's examples interactively
by running the Python interpreter, for example:

$ python
Python 2.7.3 (default, Jan  2 2013, 16:53:07)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> mystring = 'a new string object'
>>> type(mystring)

>>> mystring.upper()
'A NEW STRING OBJECT'
>>> 'another new string'.upper()
'ANOTHER NEW STRING'
>>> 'yet another string'.split()
['yet', 'another', 'string']

>>> exit()

Typing in the first >>> line
>>> mystring = 'a new string object'
creates a string object.

Typing in the next >>> line
>>> type(mystring)
shows that mystring is of type str, which is the built in class for
strings. So the mystring object is an instance created from class str.

Typing in the next line
>>> mystring.upper()
shows that the mystring object possesses a built in method named
upper() that knows how to return an upper case copy of itself.

Typing in the next line
>>> 'another new string'.upper()
shows that any/every string knows how to do the same thing. Because
every string has the same method named upper(). Because every string
instance is created from the str class, and the str class defines
upper(), so every string inherits this method.

Typing in the next line
>>> 'yet another string'.split()
shows that any/every string has a method named split() that knows how
to return a list of individual words in the string. This method is
also defined by the str class, and so is inherited by every string.

> Do you follow things so far?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Understanding Classes

2014-01-20 Thread Alan Gauld

On 20/01/14 00:55, Christian Alexander wrote:

I would first like to state two things, those being that I am a horrible
writer as well as explaining things, but Ill try my absolute best.
  Everything python is an object.  Strings, integers, lists, so on and
so forth.  In regards to classes and their relativity towards objects, I
am at complete standstill.


OK, we need to backup a little.

Objects are the individual instances of data that we work with.
This individual strings like 'foo' and 'hello' are objects.
Strings in general are a class. 'foo' and 'bar' are instances of that 
class, or objects of that class. (instance and object are almost synonymous)


Similarly for integers. 3,5,97 and 123456789 are all instances
of the integer class.

Of course these are built in classes of object so you don't see an 
explicit class defined anywhere. But classes that you define are just 
like those built in types. You define the structure and behaviour in the 
class and create instances of it to work with as objects.



However, I understand that classes are
parallel to that of a blueprint,


Yes, they define what the objects will look like, what data and what 
methods they contain. But to use those objects you have to instantiate 
them and its there that the usage varies slightly from the built in types:


For built in string type objects you do this

mystring = 'a new string object'

But if String were a user defined class you'd need to do this:

mystring = String('a user defined string object')

ie. you'd 'call' the class name with the data arguments needed.
In fact in Python you can explicitly call str() if you really
want to, missing it out is a convenience.

After that initial object creation you would use mystring identically 
regardless of whether it was user defined or built in. So we can call 
methods of the class using the instance like:


mystring.upper()
mystring.split()

etc

Do you follow things so far? It's important to understand the usage of 
classes and objects before we start worrying about the internal

details.

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos

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


Re: [Tutor] Understanding Classes

2014-01-20 Thread Christian Alexander
I would first like to state two things, those being that I am a horrible
writer as well as explaining things, but Ill try my absolute best.
 Everything python is an object.  Strings, integers, lists, so on and so
forth.  In regards to classes and their relativity towards objects, I am at
complete standstill.  However, I understand that classes are parallel to
that of a blueprint, but that is unfortunately where the buck stops.

On Sun, Jan 19, 2014 at 6:50 PM, Alan Gauld wrote:

> On 19/01/14 21:59, Christian Alexander wrote:
>
>> Looked all over the net for class tutorials
>> Unable to understand the "self" argument
>> Attempting to visual classes
>>
>
> If you read my OOP tutorial there is a section there specifically about
> self.
>
> And the v3 tutor includes an introduction to the formal visualisation
> technique for OOP called UML. The diagrams illustrating the designs may
> help.
>
> http://www.alan-g.me.uk/l2p/tutclass.htm
>
>
>  I have searched high and low, for easy to follow tutorials regarding
>> classes.  Although I grok the general concept of classes,
>>
>
> Do you also grok the concept of objects?
> Classes on their own are fairly useless (unless you are using Java)
> it is only when you create a universe of objects from those classes that
> they become useful.
>
> If you can repeat to us your understanding of classes and their
> relationship with objects that will help us understand your
> level and shape our responses accordingly.
>
>
>  to visually understand what exactly "self" does, or why it is even
>> necessary.  It seems very "magic" to me.
>>
>
> When you define a class you define the data (attributes) that
> the class instances will have. Each instance will have a copy of the data
> defined in the __init__() method.
> You also define a set of operations or methods that are associated
> with the class. Those methods are shared by the instances.
>
> Note the difference. Instances get a copy of the attributes
> but they all share the methods.
>
> Thus when you invoke a method on an instance the instance relays that call
> to the class. For the class to know which instance is being operated on,
> and for the method to be able to access the correct instance's data it
> needs a reference to the instance. That reference
> is typically called 'self' or 'this'. (In some languages it's fixed
> but in Python self is only a convention, you can use any name you like).
>
> You can make the call to the class explicit and it will still work.
> See below:
>
> # define a class
> class MyClass:
> def __init__(self,x): self.x = x
> def myMethod(self): print(self.x)
>
> # create some instances
> ObjA = MyClass(2)
> ObjB = MyClass(4)
> ObjC = MyClass(6)
>
> # send some messages/call methods
> objA.myMethod()   # call from the instance
> MyClass.myMethod(ObjB)  # call explicitly to the class
> objC.myMethod()  # direct again
>
> All 3 calls do the same thing except the middle one
> passes the object identifier directly to the class
> whereas the first and last both do that internally
> within the object structure.
>
>
>  difficult with the "__init__()" method in classes,
>>
> > and why that is also required.
>
> It is not *required* as such. You can create a class
> without an init but it's unusual.
>
> When you create an instance of a class it creates a
> data structure in memory referenced by the name of
> the instance. But that structure is empty, it has
> no data. So to populate the data for the instances
> you must initialize it. That's what __init__() does.
> It takes the arguments you provide and applies them
> to the instance along with any static data definitions
> you may define.
>
> In the example we create an instance variable, x,
> within the instances and assign the value of the
> argument passed to init. Like any other method the
> actual code lives in the class so we could initialize
> it by calling init like so:
>
> MyClass.__init__(objC, 66)
>
> which is almost the same as doing:
>
> objC = MyClass(66)
>
> The difference is that the first case requires the object ObjC
> to already exist, the second example creates a new instance and
> then calls init on that instance.
>
>
>  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.
>>
>
> Most programming concepts have visual representations,
> its just that program code being text tends to lead programmers
> to be verbally based. But algorithms, state machines, logic, data
> structures, GUIs, formal requirements and OOP all have well
> established visual representations, and in many cases they
> are formalized so that, with the right tools, you can
> create code purely visually.
>
> If the above doesn't clarify things, and I suspect it won't
> entirely, then please do express your understanding so far
> in your own words and we'll try to clarify things from there.
>
> --
> Alan G
> Author of the Learn to Program web site

Re: [Tutor] Understanding Classes

2014-01-19 Thread Alan Gauld

On 19/01/14 21:59, Christian Alexander wrote:

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


If you read my OOP tutorial there is a section there specifically about 
self.


And the v3 tutor includes an introduction to the formal visualisation
technique for OOP called UML. The diagrams illustrating the designs may 
help.


http://www.alan-g.me.uk/l2p/tutclass.htm


I have searched high and low, for easy to follow tutorials regarding
classes.  Although I grok the general concept of classes,


Do you also grok the concept of objects?
Classes on their own are fairly useless (unless you are using Java)
it is only when you create a universe of objects from those classes that 
they become useful.


If you can repeat to us your understanding of classes and their 
relationship with objects that will help us understand your

level and shape our responses accordingly.


to visually understand what exactly "self" does, or why it is even
necessary.  It seems very "magic" to me.


When you define a class you define the data (attributes) that
the class instances will have. Each instance will have a copy of the 
data defined in the __init__() method.

You also define a set of operations or methods that are associated
with the class. Those methods are shared by the instances.

Note the difference. Instances get a copy of the attributes
but they all share the methods.

Thus when you invoke a method on an instance the instance relays that 
call to the class. For the class to know which instance is being 
operated on, and for the method to be able to access the correct 
instance's data it needs a reference to the instance. That reference

is typically called 'self' or 'this'. (In some languages it's fixed
but in Python self is only a convention, you can use any name you like).

You can make the call to the class explicit and it will still work.
See below:

# define a class
class MyClass:
def __init__(self,x): self.x = x
def myMethod(self): print(self.x)

# create some instances
ObjA = MyClass(2)
ObjB = MyClass(4)
ObjC = MyClass(6)

# send some messages/call methods
objA.myMethod()   # call from the instance
MyClass.myMethod(ObjB)  # call explicitly to the class
objC.myMethod()  # direct again

All 3 calls do the same thing except the middle one
passes the object identifier directly to the class
whereas the first and last both do that internally
within the object structure.


difficult with the "__init__()" method in classes,

> and why that is also required.

It is not *required* as such. You can create a class
without an init but it's unusual.

When you create an instance of a class it creates a
data structure in memory referenced by the name of
the instance. But that structure is empty, it has
no data. So to populate the data for the instances
you must initialize it. That's what __init__() does.
It takes the arguments you provide and applies them
to the instance along with any static data definitions
you may define.

In the example we create an instance variable, x,
within the instances and assign the value of the
argument passed to init. Like any other method the
actual code lives in the class so we could initialize
it by calling init like so:

MyClass.__init__(objC, 66)

which is almost the same as doing:

objC = MyClass(66)

The difference is that the first case requires the object ObjC
to already exist, the second example creates a new instance and
then calls init on that instance.


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.


Most programming concepts have visual representations,
its just that program code being text tends to lead programmers
to be verbally based. But algorithms, state machines, logic, data 
structures, GUIs, formal requirements and OOP all have well

established visual representations, and in many cases they
are formalized so that, with the right tools, you can
create code purely visually.

If the above doesn't clarify things, and I suspect it won't
entirely, then please do express your understanding so far
in your own words and we'll try to clarify things from there.

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos

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