简体   繁体   English

将对象类型作为参数传递

[英]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.我可能可以很容易地用 if 语句做一些事情并一起破解(比如, if fruit_type==1 , test=Apple() , if f fruit_type == 2 , test=Orange()等...),但试图作为一名python程序员进行改进,我想知道是否有更好的方法来做到这一点。 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:如果您只是使用类名调用 create_fruit 然后实例化参数会怎样:

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: (编辑以将赋值添加到“测试”变量)或者你也可以做这样的事情,这实际上允许你在 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对于如此简单的任务,我只需使用 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()? python 有相当于 Java Class.forName() 的吗?

Can you use a string to instantiate a class? 你能用一个字符串来实例化一个类吗?

how to dynamically create an instance of a class in python? 如何在python中动态创建类的实例?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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