Creating Classes

0 views
Skip to first unread message

seafoid

unread,
Dec 18, 2009, 2:21:14 PM12/18/09
to pytho...@python.org

Hey Guys,

I have started to read over classes as a brief respite from my parsing
problem.

When a class is defined, how does the class access the data upon which the
class should act?

Example:

class Seq:

def __init__(self, data, alphabet = Alphabet.generic_alphabet):
self.data = data
self.alphabet = alphabet

def tostring(self):
return self.data

def tomutable(self):
return MutableSeq(self.data, self.alphabet)

def count(self, item):
return len([x for x in self.data if x == item])

I know what it should do, but have no idea how to feed it the data.

Methinks I need to invest in actual computing books as learning from
biologists is hazy!

Kind regards,
Seafoid.

--
View this message in context: http://old.nabble.com/Creating-Classes-tp26848375p26848375.html
Sent from the Python - python-list mailing list archive at Nabble.com.

Steve Holden

unread,
Dec 18, 2009, 4:09:28 PM12/18/09
to pytho...@python.org
seafoid wrote:
> Hey Guys,
>
> I have started to read over classes as a brief respite from my parsing
> problem.
>
> When a class is defined, how does the class access the data upon which the
> class should act?
>
> Example:
>
> class Seq:
>
> def __init__(self, data, alphabet = Alphabet.generic_alphabet):
> self.data = data
> self.alphabet = alphabet
>
> def tostring(self):
> return self.data
>
> def tomutable(self):
> return MutableSeq(self.data, self.alphabet)
>
> def count(self, item):
> return len([x for x in self.data if x == item])
>
> I know what it should do, but have no idea how to feed it the data.
>
> Methinks I need to invest in actual computing books as learning from
> biologists is hazy!
>
> Kind regards,
> Seafoid.
>

Supposing you create an instance of your Seq class

seq = Seq("aggadgaga")

When you call (let's say) the tostring() method of the *instance* the
interpreter automatically provides that as the first (self) argument to
the method call.

So in fact

seq.tostring()

is exactly the same as

Seq.tostring(seq)

but considerably shorter and easier to understand. Try asking the
interpreter what Seq.tostring and seq.tostring are, and you will find
one is an
unbound method", the other is a "bound method" (which means "bound to a
given instance" - in other words, it "knows" which instance it's a
method *of*.

Does this clarify it or make it more obscure?

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS: http://holdenweb.eventbrite.com/

seafoid

unread,
Dec 18, 2009, 4:19:28 PM12/18/09
to pytho...@python.org

Steve, that has indeed clarified matters!

Thanks!

--
View this message in context: http://old.nabble.com/Creating-Classes-tp26848375p26849864.html

Dave Angel

unread,
Dec 18, 2009, 11:05:33 PM12/18/09
to seafoid, pytho...@python.org
seafoid wrote:
> Hey Guys,
>
> I have started to read over classes as a brief respite from my parsing
> problem.
>
> When a class is defined, how does the class access the data upon which the
> class should act?
>
> Example:
>
> class Seq:
>
> def __init__(self, data, alphabet = Alphabet.generic_alphabet):
> self.data = data
> self.alphabet = alphabet
>
> def tostring(self):
> return self.data
>
> def tomutable(self):
> return MutableSeq(self.data, self.alphabet)
>
> def count(self, item):
> return len([x for x in self.data if x == item])
>
> I know what it should do, but have no idea how to feed it the data.
>
> Methinks I need to invest in actual computing books as learning from
> biologists is hazy!
>
> Kind regards,
> Seafoid.
>
>
Steve's message was good, but I feel he kind of jumped in the middle. A
class is a description of a type of object, and the behaviors and data
that each instance of the object supports.

You create the object by using the class name like a function call. The
arguments to that "call" are passed to the __init__ method.

So obj = Seq("abcd") or obj = Seq("defg", "abcdefg") would each
create an object of the class. But generally, many objects will exist,
each with different data.

The data in the object is accessed in what appears to be the "self"
namespace. The name self is just a convention, but it's the first
argument of each method of the class. So when somebody calls the
count() method, they pass 'item' a value, but self is used to refer to
that particular object's data.

So how does 'self' get assigned? That's what Steve was describing.
When you use the syntax:
obj.count("value")

you actually call the count method with self referring to "obj" and item
referring to "value". obj does double-duty here, both defining which
class' count() method will be called, and also supplying the first
parameter to the call, the "self" parameter.

There are more complex things that can go on, like creating "bound"
function objects, but I think this should get you pretty far.

One other point: you should always derive a class from some other
class, or 'object' by default. So you should being the class definition by:

class Seq(object):

Why? It mainly has to do with super(). But in any case if you omit the
'object' it's an "old style" class, and that's not even supported in
3.x, so it's better to just get in the habit before it matters.

DaveA

Alf P. Steinbach

unread,
Dec 18, 2009, 11:21:10 PM12/18/09
to
* Dave Angel -> seafoid:

>
> One other point: you should always derive a class from some other
> class, or 'object' by default. So you should being the class definition
> by:
>
> class Seq(object):
>
> Why? It mainly has to do with super(). But in any case if you omit the
> 'object' it's an "old style" class, and that's not even supported in
> 3.x, so it's better to just get in the habit before it matters.

I think it's best to mention that the above applies to Python 2.x.

In Python 3.x, writing

class Seq:

is equivalent to writing

class Seq( object ):

E.g.,

>>> class A: pass
...
>>> A.__bases__
(<class 'object'>,)
>>>
>>> class B( object ): pass
...
>>> B.__bases__
(<class 'object'>,)
>>> _


Curiously I can't find anything about 'object' in the language spec, but in the
3.1.1 standard library spec �2 "Built-in functions" it says "object is a base
for all classes."


Cheers,

- Alf

Dave Angel

unread,
Dec 18, 2009, 11:49:16 PM12/18/09
to Alf P. Steinbach, pytho...@python.org

Alf P. Steinbach wrote:
> <div class="moz-text-flowed" style="font-family: -moz-fixed">* Dave

> Angel -> seafoid:
>>
>> One other point: you should always derive a class from some other
>> class, or 'object' by default. So you should being the class
>> definition by:
>>
>> class Seq(object):
>>
>> Why? It mainly has to do with super(). But in any case if you omit
>> the 'object' it's an "old style" class, and that's not even supported
>> in 3.x, so it's better to just get in the habit before it matters.
>
> I think it's best to mention that the above applies to Python 2.x.
>
> In Python 3.x, writing
>
> class Seq:
>
> is equivalent to writing
>
> class Seq( object ):
>

> <snip>
We were talking about 2.x And I explicitly mentioned 3.x because if
one develops code that depends on old-style classes, they'll be in
trouble with 3.x, which has no way to specify old-style classes. In
3.x, all classes are new-style. And although it'll no longer matter
whether you specify (object), it doesn't do any harm. As I said, it's a
good habit for a beginner to get into when defining classes.

DaveA

Steve Holden

unread,
Dec 19, 2009, 1:00:27 PM12/19/09
to pytho...@python.org
> One other point: you should always derive a class from some other
> class, or 'object' by default. So you should being the class definition
> by:
>
> class Seq(object):
>
> Why? It mainly has to do with super(). But in any case if you omit the
> 'object' it's an "old style" class, and that's not even supported in
> 3.x, so it's better to just get in the habit before it matters.
>
With respect, unless you have to expound on the differences between the
old-style and the new-style classes (which aren't relevant here) you are
just introducing a red herring by even mentioning it. The average Python
user won't need to use super() in their first year as a Python programmer.

And, since you brought up Python 3, it's not necessary to explicitly
inherit from object to get new-style classes because, as you correctly
point out, old-style classes don't exist in Python 3.

I have no idea why you think "you should always derive a class from some
other class". That's pretty unnecessary.

Dave Angel

unread,
Dec 19, 2009, 9:43:30 PM12/19/09
to Steve Holden, pytho...@python.org
I'm not sure why, but since it changes behavior (more than just
super()), and since the old behavior is deprecated, I think it's
worthwhile to use new-style classes. And although you don't need to
explicitly do it in Python 3.x, it does no harm.

DaveA


Steve Holden

unread,
Dec 20, 2009, 11:11:54 AM12/20/09
to Dave Angel, Alf P. Steinbach, pytho...@python.org
Dave Angel wrote:
[...]

> We were talking about 2.x And I explicitly mentioned 3.x because if
> one develops code that depends on old-style classes, they'll be in
> trouble with 3.x, which has no way to specify old-style classes. In
> 3.x, all classes are new-style. And although it'll no longer matter
> whether you specify (object), it doesn't do any harm. As I said, it's a
> good habit for a beginner to get into when defining classes.
>
I maintain that this almost-cargo-cult belief over-complicates things
for language beginners. How long do you have to be using Python before
you make your first super() call? How many programs behave differently
with old-style vs. new-style classes?

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119

PyCon is coming! Atlanta, Feb 2010 http://us.pycon.org/

Steve Holden

unread,
Dec 20, 2009, 11:11:54 AM12/20/09
to pytho...@python.org, Alf P. Steinbach, pytho...@python.org

Steven D'Aprano

unread,
Dec 21, 2009, 2:53:51 AM12/21/09
to
On Sun, 20 Dec 2009 11:11:54 -0500, Steve Holden wrote:

> Dave Angel wrote:
> [...]
>> We were talking about 2.x And I explicitly mentioned 3.x because if
>> one develops code that depends on old-style classes, they'll be in
>> trouble with 3.x, which has no way to specify old-style classes. In
>> 3.x, all classes are new-style. And although it'll no longer matter
>> whether you specify (object), it doesn't do any harm. As I said, it's
>> a good habit for a beginner to get into when defining classes.
>>
> I maintain that this almost-cargo-cult belief over-complicates things
> for language beginners. How long do you have to be using Python before
> you make your first super() call?

That depends on who you are and what you're doing.

Are you a n00b who has never programmed before?

An old Fortran or Pascal dinosaur who doesn't like that new fangled
object stuff?

A former Java OO guru whose class hierarchies are 85 classes deep on
average?

Someone who just discovered multiple inheritance and now everything looks
like a nail?

> How many programs behave differently
> with old-style vs. new-style classes?

Any program that uses properties will behave differently.

__getattribute__ and __slots__ will not work at all in old-style classes.

There will be subtle differences, e.g. isinstance(type, MyClass) will
return False if MyClass is old-style. The default repr and str of
instances will look different (which may or may not count as different
behaviour). Speed and efficiency will be different.

So I guess the correct answer to your question is "All of them". The
interesting question is, what's the magnitude of the differences?

The advice I used to give was, unless you care about the difference,
always inherit from object because new-style classes are the way of the
future. Unfortunately, it is no longer obvious whether something in
isolation is a new-style or old-style class, as you have to know the
target Python version.


--
Steven

Reply all
Reply to author
Forward
0 new messages