将对象类型作为参数传递

Passing Object Type as Parameter

我有一些代码希望以比我的直觉想要的更优雅的方式实现。我会尽力描述我正在尝试的。

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

好的,希望这段代码能说明一些问题。我在一个模块中有一个函数,它使用一堆参数来创建 class 的实例。理想情况下,我想传递一个参数,说明要创建的 class 的类型(但它们都是同一个 superclass 的实例或 subclasses)。每个 subclass 的参数将是相同的(截至目前)。

我可能可以很容易地用 if 语句做一些事情并将其组合在一起(比如,if fruit_type==1test=Apple()、if fruit_type == 2test=Orange(),等等……) ,但在尝试提高 python 程序员的过程中,我想知道是否有更好的方法来做到这一点。我已经简要阅读了装饰器和函数式编程(尽管它对我来说仍然很抽象,并且需要更多时间来思考),所以也许这也是同样的道理?

对于这样一个简单的任务,我会简单地使用字典

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?

如果您只是使用 class 名称调用 create_fruit 然后实例化参数会怎么样:

def create_fruit(fruit_type):
    test = fruit_type()

create_fruit(Apple)

(编辑以将赋值添加到 "test" 变量) 或者你也可以做这样的事情,这实际上允许你在 create_fruit:

之外用你创造的水果做一些事情
def create_fruit(fruit_type):
    return fruit_type()

test = create_fruit(Apple)
test.bite()

您可以使用检查找到可用的 类 并从那里创建实例

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