将对象类型作为参数传递

时间:2019-12-20 20:00:24

标签: python python-3.x python-3.8

我想以一种比我的直觉想要的方式更优雅的方式实现一些代码。我将尽我所能描述我的尝试。

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

好吧,所以希望这段代码有意义。我在模块中有一个函数,该函数需要一堆参数来创建类的实例。理想情况下,我想传递一个参数来说明要创建哪种类型的类(但它们都将是同一超类的实例或子类)。每个子类的参数都相同(到目前为止)。

如果语句很容易被黑(例如if fruit_type==1test=Apple(),i f fruit_type == 2test=Orange()等),我可能可以做一些事情,但是在尝试改进为python程序员的过程中,我想知道是否有更好的方法可以做到这一点。我已经简要阅读了装饰器和函数式编程(尽管对我来说仍然很抽象,并且需要花更多的时间来思考),所以也许是同样的道理?

3 个答案:

答案 0 :(得分:2)

如果只用类名调用create_fruit然后实例化参数,该怎么办?

def create_fruit(fruit_type):
    test = fruit_type()

create_fruit(Apple)

(已编辑以将分配添加到“测试”变量中) 或者,您也可以执行类似的操作,这实际上允许您对create_fruit之外的已创建水果执行某些操作:

def create_fruit(fruit_type):
    return fruit_type()

test = create_fruit(Apple)
test.bite()

答案 1 :(得分:1)

您可以使用inspect查找可用的类,然后从那里创建实例

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

答案 2 :(得分:0)

对于这样一个简单的任务,我只使用字典即可​​。

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)

以下是您的问题的重复副本

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?