Reputation: 1313
I would like to implement the following structure:
class Case(nx.Graph):
def __init__(self, case):
if case == 1:
self = Case1()
if case == 2:
self = Case2()
class Case1(Case):
def __init__(self):
super(Case1, self).__init__()
print "Case1"
class Case2(Case):
def __init__(self):
super(Case2, self).__init__()
print "Case2"
For instance, if I create the following object:
graph = Case(1)
a new Object of the class Case1
should be created. In the __init__
of the class Case1
the super()
fuction should call the __init__
function of the networkx.Graph()
.
If I run that code, the result should be a networkx.Graph
object called "graph" and it should print Case1
.
Upvotes: 1
Views: 115
Reputation: 948
This is a classic Factory pattern. I would implement it using a static method as follows:
class Case(object):
@staticmethod
def factory(case):
if case == 1:
return Case1()
if case == 2:
return Case2()
raise NotImplementedError('Unknown case: %r'%case)
class Case1(Case):
def __init__(self):
super(Case1, self).__init__()
print "Case1"
class Case2(Case):
def __init__(self):
super(Case2, self).__init__()
print "Case2"
You can extend as appropriate for args to pass to the initializer. IN usage, you might see something like the following:
c1 = Case.factory(1)
c2 = Case.factory(2)
print type(c1), type(c2)
Case.factory(3)
Output would look like this:
Case1
Case2
<class '__main__.Case1'> <class '__main__.Case2'>
Traceback (most recent call last):
File "<string>", line 36, in <module>
File "<string>", line 19, in factory
NotImplementedError: Unknown case: 3
Upvotes: 0
Reputation: 152577
One way of doing it is by not invoking __init__
for the subclasses but putting these in a seperate method, i.e. setup
and rewriting the __class__
attribute:
class Case(object):
def __init__(self, case):
# Maybe even call the init of the superclass:
super(Case, self).__init__()
# Do the setup that is common to all Cases:
self.setup()
# Change the class of the instance depending on your case:
if case == 1:
self.__class__ = Case1 # No () here!
elif case == 2:
self.__class__ = Case2
else:
raise ValueError()
# Call the setup of the subclass
self.setup()
def setup(self):
print('Setup of Case called.')
class Case1(Case):
def setup(self):
print('Setup of Case1 called.')
class Case2(Case):
def setup(self):
print('Setup of Case2 called.')
when I try to create a Case1
:
a = Case(1)
it prints:
Setup of Case called.
Setup of Case1 called.
But there might even be proper (builtin-modules, packages) recipes for doing something like this.
Upvotes: 0
Reputation: 20336
When you say self = ...
, you are just redefining self
. You aren't changing it. To do what you want, use __new__
instead:
class Case(nx.Graph):
def __new__(self, case):
if case == 1:
return Case1()
elif case == 2:
return Case2()
else:
raise ValueError("Invalid argument")
You really shouldn't do this, though. If you want a different instance for a different case, do it when you create the instance, but a class should not depend on its children in order to work.
Upvotes: 1