简体   繁体   中英

Passing Object Type as Parameter

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() , i f 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?

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()

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

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM