【问题标题】:Passing Object Type as Parameter将对象类型作为参数传递
【发布时间】:2019-12-20 20:00:24
【问题描述】:

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

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 语句做一些事情并一起破解(例如,if fruit_type==1test=Apple()、if fruit_type == 2test=Orange() 等……),但作为一名 Python 程序员,我试图提高自己,我想知道是否有更好的方法来做到这一点。我已经简要阅读了装饰器和函数式编程(尽管它对我来说仍然很抽象,并且需要更多时间来理解),所以也许这也是同样的道理?

【问题讨论】:

  • Apple 和 Orange 是否具有相同的参数和方法,或者它们是否完全不同,例如 Apple 和汽车?
  • 它们现在具有所有相同的参数,但很可能具有不同的方法。

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


【解决方案1】:

如果你只是用类名调用 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()

【讨论】:

  • 在撰写本文时看到的三个答案中,我最喜欢这个解决方案。非常简单,完全符合我的需要。谢谢!
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    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?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多