faqts : Computers : Programming : Languages : Python : Language and Syntax : Classes

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

14 of 16 people (88%) answered Yes
Recently 9 of 10 people (90%) answered Yes

Entry

Can a class have two __init__ functions with different argument lists?

Sep 25th, 2003 10:05
Paul McGuire, Michael Hudson, Mark Tomko, http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52304


No, not really.

There are workarounds; the lowest-tech is something along the lines of:

class C:
    def __init__(*args):
        if len(args) == 1:
            apply(args[0].init0,args)
        else:
            apply(args[0].init1,args)
    def init0(self):
        print "no args!"
    def init1(self):
        print "one arg!"

Also, in some circumstances it may be possible to create the instance
using the new module and then choose which initialization function to
call.  This is definitely an experts only solution...  I have used it in
eg:

http://cvs.sourceforge.net/cgi-
bin/cvsweb.cgi/bytecodehacks/bytecodehacks/code_editor.py?
rev=1.7.2.1&content-type=text/x-cvsweb-markup&cvsroot=bytecodehacks

(nice long url, sorry)

about 40 lines in.


<<added 18/Sept/2003>>
An alternative is to create class-level methods for constructing new 
instances.  This is sort of a C++-ish technique (but I've seen it in 
Smalltalk too), and it requires using a small wrapper class to convert 
the defined instance function into a class function, but I think it 
works well.  Here is a simple example of a Color class with an ordinary 
initializer taking 3 integers, each for red, green, and blue, and then 
a class level factory method named fromLong that takes a single long 
integer (such as might be found in a bitmap palette).


class Color:
  """class for specifying colors while drawing BitMap elements"""
  def __init__( self, r=0, g=0, b=0 ):
    self.red = r
    self.grn = g
    self.blu = b
    
  def __str__( self ):
    return "R:%d G:%d B:%d" % (self.red, self.grn, self.blu )
  
  def toLong( self ):
    return ( long(self.blu)       ) + \
           ( long(self.grn) <<  8 ) + \
           ( long(self.red) << 16 )

  def fromLong( l ):
    blu = l & 0xff
    l = l >> 8
    grn = l & 0xff
    l = l >> 8
    red = l & 0xff
    return Color( red, grn, blu )
  fromLong = staticmethod(fromLong)


c = Color( 255, 0, 0 ) # red
print c
colorInt = c.toLong()
print colorInt
print Color.fromLong( colorInt )