many constructors in a class?

C

climb65

Hello,

here is a small basic question :

Is it possible to have more than one constructor (__init__ function) in a
class? For instance, to create an object with 2 different ways? If my
memory is good, I think that with C++ it is possible.

Thanks for your answer.
 
B

Beth McNany

Hello,

here is a small basic question :

Is it possible to have more than one constructor (__init__ function) in a
class? For instance, to create an object with 2 different ways? If my
memory is good, I think that with C++ it is possible.

Thanks for your answer.
No, Python does not allow method overloading:
.... def __init__(self):
.... print "first init"
.... def __init__(self, arg):
.... print "init with arg"
....Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() takes exactly 2 arguments (1 given)

No error on actually writing the class, but only the last __init__ is
kept. You could, however, emulate that behavior with optional arguments,
or something more sophisticated as the need may be. This stackoverflow
question covers a few alternatives:
http://stackoverflow.com/questions/6434482/python-function-overloading
 
P

Phil Le Bienheureux

2013/8/14 climb65 said:
Hello,

here is a small basic question :

Is it possible to have more than one constructor (__init__ function) in a
class? For instance, to create an object with 2 different ways? If my
memory is good, I think that with C++ it is possible.

Thanks for your answer.



Hello,

You have to use default values in __init__ function, like :
def __init__( self, name = None ):
self.name_ = name

and afterwards in your code, test variable :
if self.name_:
do something...

Regards,
Phil.
 
D

Dennis Lee Bieber

Hello,

here is a small basic question :

Is it possible to have more than one constructor (__init__ function) in a
class? For instance, to create an object with 2 different ways? If my
memory is good, I think that with C++ it is possible.
Well... Secret Python-Fu -- __init__() is NOT a constructor. The
constructor is __new__(); __init__() is just an initializer of whatever
__new__() creates.


Ignoring that detail... NO!

If the goal is to be able to "leave out" some parameters, that is
performed by setting default values for the missing parameters.

def __init__(self, these, are, mandatory, but=None, this=None,
is=None, optional=None):
self.these = these
self.are = are
self.mandatory = mandatory
if but is None:
self.but = these + are
else:
self.but = but
#etc.
 
S

Steven D'Aprano

Hello,

here is a small basic question :

Is it possible to have more than one constructor (__init__ function) in
a class? For instance, to create an object with 2 different ways? If my
memory is good, I think that with C++ it is possible.

Thanks for your answer.

Yes it is. The built-in type dict is a good example, there is the regular
default constructor[1] that you can call like this:

dict([('a', 100), ('b', 200)], spam=1, ham=2, eggs=3)


Plus there is an alternative constructor that you can call like this:

dict.fromkeys(['a', 'b', 'spam', 'ham', 'eggs'])


The way to create an alternative constructor is to use a class method:


def MyDict(dict):
@classmethod
def fromkeys(cls, keys):
...


If you need further details, please ask.




[1] The constructor is __new__, not __init__. __init__ is called to
initialise the instance after __new__ constructs it.
 
F

Fábio Santos

I agree with Steven here.

classmethod is the best practise, most practical, readable, future-proof,
one obvious way to do it.
Hello,

here is a small basic question :

Is it possible to have more than one constructor (__init__ function) in
a class? For instance, to create an object with 2 different ways? If my
memory is good, I think that with C++ it is possible.

Thanks for your answer.

Yes it is. The built-in type dict is a good example, there is the regular
default constructor[1] that you can call like this:

dict([('a', 100), ('b', 200)], spam=1, ham=2, eggs=3)


Plus there is an alternative constructor that you can call like this:

dict.fromkeys(['a', 'b', 'spam', 'ham', 'eggs'])


The way to create an alternative constructor is to use a class method:


def MyDict(dict):
@classmethod
def fromkeys(cls, keys):
...


If you need further details, please ask.




[1] The constructor is __new__, not __init__. __init__ is called to
initialise the instance after __new__ constructs it.
 
R

Roy Smith

Steven D'Aprano said:
[1] The constructor is __new__, not __init__. __init__ is called to
initialise the instance after __new__ constructs it.

True, but be warned that writing your own __new__() is quite rare and
probably falls into the realm of dark magic. If you're just starting
out, learn about __init__(), and don't worry about __new__() at all.

For those of you coming from a C++ background, Python's __init__() is
like C++'s constructor, and __new__() is more like operator new. That's
not a perfect analogy from a functional standpoint, but it's a good
guide for how often you'll want to write each one.

And then, of course, there's __enter__() and __exit__(), which are like
C++'s constructor and destructor, but that's another story :)
 

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

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top