how to use more than 1 __init__ constructor in a class ?

S

scott

hi people,

can someone tell me, how to use a class like that* (or "simulate" more
than 1 constructor) :
#--
class myPointClass:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __init__(self, x=0, y=0, z=0):
self.__init__(self, x, y)
self.z = z
#--

tia people
scott

*this is not homework
 
M

Michael Hoffman

scott said:
can someone tell me, how to use a class like that* (or "simulate" more
than 1 constructor) :
#--
class myPointClass:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __init__(self, x=0, y=0, z=0):
self.__init__(self, x, y)
self.z = z
#--

Well for the example you used, multiple constructors are not needed.
This will get you the same result as what I imagine you wanted the
first example to do:

class myPointClass:
def __init__(self, x=0, y=0, z=0):
self.x = x
self.y = y
self.z = z
 
S

Steve

Hi Scott,
can someone tell me, how to use a class like that* (or "simulate" more
than 1 constructor) :

One approach could be:

class myPointClass:
def __init__(self, **args):
for k, v in args.items():
setattr(self, k, v)
*this is not homework
Just to be safe, I'll leave out the explanation :)

Regards
Steve
 
R

Rocco Moretti

scott said:
hi people,

can someone tell me, how to use a class like that* (or "simulate" more
than 1 constructor) :
#--
class myPointClass:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __init__(self, x=0, y=0, z=0):
self.__init__(self, x, y)
self.z = z
#--

You might try:

#--
class myPointClass:
def __init__(self, x=0, y=0, z=None):
self.x = x
self.y = y
if z is not None:
self.z = z
#--

You could also turn __init__ into a dispatch fuction:

#--
class myPointClass:
def __init__(self, *args):
if len(args) <= 2:
self.__init_two(*args)
if len(args) == 3:
self.__init_three(*args)
def __init_two(self, x=0, y=0):
self.x = x
self.y = y
def __init_three(self, x=0, y=0, z=0):
self.__init_two(x, y)
self.z = z
#--

But I would definitely recommend looking at your algorithm to determine
if there is a better way to do what you want, that doesn't require an
initilizer with two different signatures.
 
P

Paul McGuire

This recipe that I submitted to the Python Cookbook
(http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/223611)
describes a technique for doing this. I use the example of creating
Color objects for plotting to a bitmap, using either R,G,andB values,
or a single integer representing the RGB encoded value.

This style you describe is a Java language artifact. If you have
optional params, then these really don't represent different method
signatures. In my color example, you truly have different signatures,
either 3 integers representing color components, or a single encoded
integer.

-- Paul
 
W

wittempj

You also could use a list to represent your data, then you get more
dimensions supported, e.g:
import math
class Point:
def __init__(self, *args):
self.points = list(args)

def dist(x, y):
if len(x.points) != len(y.points):
raise RuntimeError('dimensions not the same')
d = 0
for i in range(len(x.points)):
d += (x.points - y.points)**2
return math.sqrt(d)
 
F

F. Petitjean

Le 22 Jun 2005 11:44:09 -0700, (e-mail address removed) a écrit :
You also could use a list to represent your data, then you get more
dimensions supported, e.g:
import math
class Point:
def __init__(self, *args):
self.points = list(args)

def dist(x, y):
if len(x.points) != len(y.points):
raise RuntimeError('dimensions not the same')
d = 0
for i in range(len(x.points)):
d += (x.points - y.points)**2
return math.sqrt(d)


My rewrite (same idea) :)
class Point(object):
def __init__(self, *args):
self.coords = list(args) # or even args ?

def dist(self, other):
d2 = sum([ (c1-c2)*(c1-c2) for c1, c2 in zip(self.coords,
other.coords)])
return math.sqrt(d2)
 
R

Roy Smith

scott said:
hi people,

can someone tell me, how to use a class like that* (or "simulate" more
than 1 constructor) :
#--
class myPointClass:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __init__(self, x=0, y=0, z=0):
self.__init__(self, x, y)
self.z = z

Python does not have the kind of polymorphism that C++ or Java has.
There is only a single copy of each method (including __init__) for
each class, but methods can take variable numbers of arguments, with
default values. You probably want something like:

def __init__(self, x=0, y=0, z=0):
self.x = x
self.y = y
self.z = z

You can call this with 0, 1, or 2 arguments, i.e. any of the following
are legal:

MyClass() # x, y, and z all get defaulted to 0
MyClass(1) # x=1, y and z both default to 0
MyClass(1, 2) # x=1, y=2, z defaults to 0
MyClass(1, 2, 3) # x=1, y=2, z=3

Once you get the hang of it, you'll understand just how brain-dead C++
and Java really are :)

Take a look at http://docs.python.org/ref/function.html for more
details.
 
J

Jeffrey Maitland

Well one way to do this (not sure if it is the best way) is something like.

class mypoint:
def __init__(self, *args):
len_args = len(args)
print len_args
if len_args == 0:
self.x = 0
self.y = 0
self.z = 0
elif len_args >=2 and len_args <= 3:
for i in range(len_args):
if args == None: args = 0 #populating the list of
args with defgault values if null(None)
self.x = kargs[0]
self.y = kargs[1]
if len_args == 3: self.z = args[2]
else: raise "Invalid Input"

Now this is not looking for null input such as
p = mypointclass(,,,)
this is an invalid syntax error. Now there must be away to catch for
the blanks but Iam not sure off the top of my head.
hope that helps
 
S

Steven D'Aprano

scott said:
hi people,

can someone tell me, how to use a class like that* (or "simulate" more
than 1 constructor) :
#--
[snip]

You could also turn __init__ into a dispatch fuction:

#--
class myPointClass:
def __init__(self, *args):
if len(args) <= 2:
self.__init_two(*args)
if len(args) == 3:
self.__init_three(*args)

Oh wow, so that's what I've been doing for years. Dispatching.

And I thought I was just calling other functions :)

That's the joys of a mostly self-taught programming knowledge: you miss
out on all the buzzwords.
 
R

Rocco Moretti

Steven said:
Oh wow, so that's what I've been doing for years. Dispatching.

And I thought I was just calling other functions :)

I think the distinction between just calling other functions and
dispatching is that with dispatching, the function doesn't do any actual
work by itself, but just hands off the work to a different function.

http://www.c2.com/cgi/wiki?DispatchingForDummies
That's the joys of a mostly self-taught programming knowledge: you miss
out on all the buzzwords.

Being mostly self taught myself, I have a tendancy to use infrequently
encountered terms in related but technically inappropriate contexts,
confusing the better informed people I deal with. ;-)
 
S

Singletoned

Rocco said:
Steven D'Aprano wrote:

Being mostly self taught myself, I have a tendancy to use infrequently
encountered terms in related but technically inappropriate contexts,
confusing the better informed people I deal with. ;-)

Indeed. I find I use even more buzzwords because I can just make up as
many as I want.
 
J

jean-marc

Singletoned said:
Indeed. I find I use even more buzzwords because I can just make up as
many as I want.
This thread 'branch' (humm, is this an appropriate term for the last
few quotes, going to Steven's?) is soothing in reminding us we are not
alone. That there is a sort of distributed 'Alma Mater' of the
'Teach-It-Yourself School of Computing', producing a virtual FOAF group
(Is FOAF, Friend Of A Friend or Flock Of A Feather?)

jm
 
T

Terry Hancock

Indeed. I find I use even more buzzwords because I can just make up as
many as I want.

As fun as that is ;-), it does make it hard to communicate. It seems to me
that I spend a lot of time trying to figure out what buzzwords mean, only
to find that 9/10ths of them are for things I've already done somewhere.

Of course, that 10th one can be a doozy, "metaclasses" comes to mind.

And it does make it easier to find help on problems, if you know what
other people call them.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,591
Members
45,103
Latest member
VinaykumarnNevatia
Top