Reputation: 2840
I would like to build a class which inherits from a dict
and some other classes.
Based on a key of someDict
(initial dictionary), Third
class should inherit either from First
or from Second
.
Here is a basic example:
class First(object):
def first_action(self):
print "first_action"
class Second(object):
def second_action(self):
print "second_action"
class Third(dict, First, Second):
"""This is not running code
but, rather, an example of desired functionality.
"""
if "x" == someDict["some_key"]:
third_action == First.first_action()
print third_action
else:
third_action == Second.second_action()
print third_action
A desired output:
obj = Third()
obj.third_action()
'first_action' # <- Should print this value if dict["some_key"] = "x"
'second_action' # <- if someDict["some_key"] != "x"
For more general case Third
class, based on the value of a key of someDict
, should switch between methods belonging to First
or Second
.
If action
is a method of Third
, it should switch between first_action
or second_action
.
Any suggestion is appreciated!
Upvotes: 1
Views: 1683
Reputation: 2353
As long as some_key
can be changed, the inheritance is not what you want here. Despite of the fact you technically could make this kind of chameleon class, you should definitely avoid this.
Basically, you should explicitly override all chameleon methods and call another one within, according to your condition ("x" == someDict["some_key"]
).
You also may have a look at decorator pattern. Your object may store the action
and apply different decorators according to the condition. Once again, as far as I understand the question, the condition may vary, hence must be checked every single time (and this means you should override all methods that depend on this condition).
You also may want to override all methods that could change some_key
instead of all chameleon ones: it allows to cache the result of "x" == someDict["some_key"]
while some_key
is not changing.
In comment section you say your dictionary is predefined. In this case, you should just define two different classes:
class ThirdA(dict, First)
class ThirbB(dict, Second)
Also you need some factory to choose between ThirdA
and ThirdB
for you.
class ThirdFactory(object):
@classmethod
def create(cls, dictionary):
if "x" == dict["some_key"]:
return ThirdA(dictionary)
else:
return ThirdB(dictionary)
(Factory method also works here, as long as you have suitable class to place it.)
So now you can just
my_object = ThirdFactory.create(dict(some_key='x'))
Mind that the class of the object will never change. If you want it to change, view the first part of my answer.
P. S. Don't name your dictionary dict
, that's the name of the type.
Upvotes: 3
Reputation: 1857
While assigning the function from first or second class you dont need to put parenthesis. And also I dont understand what are you doing in this line
if "x" == dict["some_key"]
Is dict some predefined dictionary then you should not use the name "dict" as it overrides the default builtin dict keyword. Assuming it is a predefined dictionary (let us name it someDict). This shoud do.
class Third(dict, First, Second):
if "x" == someDict["some_key"]:
third_action = First.first_action
print action
else:
third_action = Second.second_action
print action
Upvotes: 1
Reputation: 4912
first_action
or second_action
are not class methods so that you can not call them that way.
You could write like this:
class First(object):
def first_action(self):
print "first_action"
class Second(object):
def second_action(self):
print "second_action"
# you have to change name of that dictionary from dict to my_dict since dict is the name of a built-in class
class Third(my_dict, First, Second):
"""This is not running code
but, rather, an example of desired functionality.
"""
# define a function named third_action to achieve this
def third_action(self):
if "x" == my_dict["some_key"]:
# you have to call instance method this way
third_action == self.first_action()
print action
else:
third_action == self.second_action()
print action
You can get your expected output through this way.
Upvotes: 1