6

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?

2
  • Will Apple and Orange have the same parameters and methods OR, are they wildly different, like Apple and Automobile? Commented Dec 20, 2019 at 20:24
  • They have all the same parameters for now, but will most likely have varying methods. Commented Dec 20, 2019 at 20:56

3 Answers 3

6

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()
Sign up to request clarification or add additional context in comments.

2 Comments

Out of the three answers I saw at the time of writing this, I liked this solution the most. Very straightforward, and does exactly what I need. Thank you!
Thank you for this. I checked another question that asked the same thing. Lots of up votes and no answer like this. Lots of unnecessary lines of code that skirt around unnecessary details relevant to the actual question.
1

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

Comments

0

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?

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.