When *don't* I use 'self' in classes?

Rhodri James rhodri at wildebst.demon.co.uk
Wed May 13 19:03:41 EDT 2009


On Wed, 13 May 2009 23:36:07 +0100, Adam Gaskins  
<agaskins_ng at kelleramerica.com> wrote:

> I am a bit confused as too when, if ever, it is not appropriate to  
> prepend
> 'self' to objects in a class. All of the examples of how to use 'self'  
> that
> I find seem to be short and very simple (as examples tent to be). I
> appologize if I am asking an ignorant question here, but I want to get  
> off
> on the right foot. Here's an example of what I mean:
>
> import serial
> class foo:
>     def __init(self, comport):
>         self.comport = comport
>         self.baudrate = 9600 #default
>         self.ser = serial
>         try:
>             self.ser.Serial()
>             self.ser.baudrate = self.baudrate
>             self.ser.open()
>         except:
>             print 'Serial port could not be opened'
>
> === OR ===
> import serial
> class foo:
>     def __init(self, comport):
>         self.comport = comport
>         self.baudrate = 9600 #default
>         try:
>             ser = serial.Serial()
>             ser.baudrate = self.baudrate
>             ser.open()
>         except:
>             print 'Serial port could not be opened'
>
> There may be a typo in here, this is just a random example similar to
> something I'm working with, but which one of these are more 'proper'? If  
> I am importing a library do I still prepend it's object with self when I  
> use it in my class? I suppose my question is just basically... when do  
> you NOT prepent an object in a class with 'self'?
>
> I'm not even sure I'm using the term 'object' correctly here. Feel free  
> to set me straight, but I hope my example makes it clear what I am  
> asking.

Prepending "self" to an identifier means that what you are using is an
attribute of the class instance that you're dealing with; i.e. you're
attaching the object to the instance.  Whether or not you want to do that
depends entirely on whether you expect to use that object ever again, or
whether you're using it once and tossing it away.

For the example you give, you're most likely to want to do neither of
the above.  The first version gives you access to the entire namespace
of the "serial" module as an attribute of instances of the class "foo",
which is unlikely to be what you want.  The second, on the other hand,
creates and opens a serial port, then throws it away.  It's more likely
that you'll want something like this:

import serial
class foo:
     def __init__(self, comport):
         self.comport = comport
         self.baudrate = 9600
         try:
             self.ser = serial.Serial()
             self.ser.baudrate = self.baudrate
             self.ser.open()
         except:
             print 'Serial port could not be opened'

     def send_data(self, data):
         self.ser.write(data)

(except that a bare 'except' like that is a very bad idea (you'll catch
keyboard interrupts and the like), but let's assume that you're doing
something more detailed for the purposes of this example.)

As you can see, making the serial port itself an attribute allows you
to use it in other methods.  If you had just used "ser" as in your
second example, it would be a local variable to the method foo.__init__(),
so it would vanish when __init__ returned just like any other local
variable.  Making it an attribute keeps it around (attached to just
that one instance of the class) so that you can use it later.

In general, don't make something an attribute if you know you're never
going to reuse it.

-- 
Rhodri James *-* Wildebeeste Herder to the Masses



More information about the Python-list mailing list