Reputation: 130
I want to create a sub class "sub()" that can inherit either object "A(object)" or object "B(object)".
The following works for this:
class A(object):
def __init__(self):
print "Class A was inherited"
class B(object):
def __init__(self):
print "Class B was inherited"
class sub(A if inh==A else B):
def __init__(self,inh):
if inh==A:
A.__init__(self)
else:
B.__init__(self)
However, "inh" is not a defined parameter when I construct my "sub()". I want to be able to construct my "sub()" with an argument "inh" that initialize either "A(object)" or "B(object)".
So that:
my_object = sub(inh = A)
will give me:
Class A was inherited
And that:
my_object = sub(inh = B)
will give me
Class B was inherited
My problem is, how do I pass "inh" to the constructor "sub()" so it can choose the right object to inherit?
Upvotes: 0
Views: 208
Reputation: 77952
Immortal's solution, while basically right, has a drawback: each call to Sub()
will yield a new class, so things like isinstance()
or class identity test will break. A solution to this is to keep a mapping of already created classes:
_CLSMAP = {}
def Sub(base, *args, **kw):
if base not in _CLSMAP:
class Sub(base):
def __init__(self, *args, **kw):
super(sub, self).__init__(*args, **kw)
_CLSMAP[base] = Sub
return _CLSMAP[base](*args, **kw)
Upvotes: 2
Reputation: 3188
It would seem to me that what you want is a generator/factory function that will construct and return a class instance as you'd wish.
For that, you can use python's ability to define classes and functions within functions, so that your definition of class sub
will be done in the scope of the factory function, like this:
def Sub(inh=object):
class sub(inh):
def __init__(self):
super(sub, self).__init__()
return sub()
You can now pass the desired subclass to your generator function and get an instantiated instance of the desired type.
Run output:
>>> def Sub(inh=object):
... class sub(inh):
... def __init__(self):
... super(sub, self).__init__()
... return sub()
...
>>> class A(object):
... def __init__(self):
... print "Class A was inherited"
...
>>>
>>> class B(object):
... def __init__(self):
... print "Class B was inherited"
...
>>>
>>> Sub(A)
Class A was inherited
<__main__.sub object at 0x014E4970>
>>> Sub(B)
Class B was inherited
<__main__.sub object at 0x014E49F0>
>>>
is as desired.
Upvotes: 1