[Tutor] Proper uses of classes

Dave Angel davea at davea.name
Wed Apr 3 23:16:15 CEST 2013


On 04/03/2013 03:43 PM, frank ernest wrote:
> Hi guys, it's been a while since I posted and I've learned a lot since then. Today I have a question on classes, I can't get mine to work.

Welcome back.  I'll try.  First comment is that indentation ought to be 
4 columns, until you have enough experience to prefer something 
different.  Certainly one column makes the code nearly illegible to me.

Second comment is that deriving from a built-in class like list is 
tricky.  It won't be enough to define an __init__() method, and it turns 
out you're not using the inheritance anyway.  So please get this working 
using only object as your base.  You're probably using Python3.x, where 
object is implied, but it doesn't hurt to be specific.

class alist(object):

> class alist(list):
>   def __init__(self, b, a):
>   self = list()

You forgot to indent the body of the method.  That's an IndentationError 
during compile, so I suspect this code is NOT what you tried.  I'll 
assume you indent the lines from here through the 'def appendit' line.

Please use copy/paste to put your code into your email message.  If you 
retype it, you waste everybody's time.

Don't assign to 'self,' as once you do, you no longer have any access to 
the class instance.  It's a parameter, automatically passed to your 
method.  You probably want to add an attribute to hold the new list.

I'll assume you change it to:
     self.mylist = list()
     self.mylist.append(b)

>   self.append(b)

>   a = a + b
>   def appendit(self):
>   self.append(a)

You didn't indent again.  Further, you referenced a, which was a 
parameter to an entirely different method.  If you meant for it to be 
saved, you could have made it a new attribute in the first method, by using
     self.a = a

>  
> print(alist(2,4))

You never added anything to the list, so of course it prints out as 
empty.  You created a new one inside your class.

> []
> #It's blank!
> c = alist(2,4)
> c.appendit()
> print(c)
> [[...]]
> #It's still blank!
> If I add this:
>   a = a + b
>  
> the last line of my deffinition I get:
> c = alist(2,4)
> c.appendit()
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "<stdin>", line 7, in appendit
> UnboundLocalError: local variable 'a' referenced before assignment
> If I make a nonlocal I get
> SyntaxError: name 'a' is parameter and nonlocal
> I want it to get my list and all the members in it when printing for instance. I also would like to without making them global create two variables which I can use throughout the whole class as their value will not change.
>

If you want a custom printing behavior, you'd need to define a __str__() 
method in your class.  Since you don't, and since you inherit from list, 
you get its behavior.

I made the assumption throughout that it was a mistake to inherit from 
list.  Most of my answers could have been different if you were really 
deliberate about inheriting from list.  For example, you wouldn't be 
able to create your own list, but would have to use the one that you 
inherited from.  You'd have to define a __new__() method, and call 
list's __new__() method from it.   And if you created extra instances as 
your last sentence says, you'd have to define your own __str__() method, 
as the built in list logic wouldn't recognize anything you added.

In any case, I'd write a few successful plain classes before even 
beginning to do inheritance.

HTH

-- 
DaveA


More information about the Tutor mailing list