Reputation: 181
I have some code I am looking to implement in a more elegant way than my instincts want to do. I will do my best to describe what I am attempting.
class Fruit():
pass
class Apple(Fruit):
pass
class Orange(Fruit):
pass
def create_fruit(fruit_type):
test = ???? # code here to create instance of fruit of desired type called test
Ok, so hopefully this code makes some kind of sense. I have a function in a module that takes a bunch of parameters to create an instance of a class. I would ideally like to pass a parameter stating what type of class to create (but they would all be instances or subclasses of the same superclass). The parameters for each subclass would be the same (as of now).
I could probably do something with if statements pretty easily and hacked together (something like, if fruit_type==1
, test=Apple()
, if fruit_type == 2
, test=Orange()
, etc…), but in trying to improve as a python programmer, I wanted to know if there was a better way of doing this. I have briefly read on decorators and functional programming (though it is still quite abstract to me, and will take a little more time to wrap my head around), so perhaps this is in that same vein?
Upvotes: 6
Views: 7000
Reputation: 1209
You could find available classes using inspect and create the instance from there
import inspect
import sys
class Fruit():
pass
class Apple(Fruit):
pass
class Orange(Fruit):
pass
clsmembers = dict(inspect.getmembers(sys.modules[__name__], inspect.isclass))
def create_fruit(fruit_type):
try:
return clsmembers[fruit_type]()
except:
print('Could not match Fruit type')
fruit1 = create_fruit('Apple')
print(fruit1)
# <__main__.Apple object at 0x1105de940>
fruit2 = create_fruit('Orange')
print(fruit2)
# <__main__.Orange object at 0x1105de978>
fruit3 = create_fruit('Grape')
# Could not match Fruit type
Upvotes: 1
Reputation: 291
What if you just call create_fruit with the class name and then instantiate the parameter:
def create_fruit(fruit_type):
test = fruit_type()
create_fruit(Apple)
(edited to add the assignment to the "test" variable) Or you could do something like this too, which would actually allow you to do something with your created fruit outside of create_fruit:
def create_fruit(fruit_type):
return fruit_type()
test = create_fruit(Apple)
test.bite()
Upvotes: 6
Reputation: 73221
For such a simple task, I'd simply use a dict
def create_fruit(fruit_type):
fruits = {1: Apple, 2: Orange}
if fruit_type not in fruits.keys():
raise Exception('fruit type does\'t exist!')
klass = fruits[fruit_type]()
print(klass) # <__main__.Apple object ...>
create_fruit(1)
Here are some close duplicates to your question
Does python have an equivalent to Java Class.forName()?
Can you use a string to instantiate a class?
how to dynamically create an instance of a class in python?
Upvotes: 0