【问题标题】:Avoid if else to instantiate a class - python避免 if else 实例化一个类 - python
【发布时间】:2019-01-08 16:06:47
【问题描述】:

我想根据字段的值创建一个类的对象。

例如:

if r_type == 'abc':
                return Abc()
            elif r_type == 'def':
                return Def()
            elif r_type == 'ghi':
                return Ghi()
            elif r_type == 'jkl':
                return Jkl()

这里有什么是避免 if else 的 Pythonic 方法。我正在考虑创建一个以 r_type 为键,类名为值的字典,并获取值并实例化,这是一种正确的方式,还是在 python 中有更好的惯用方式?

【问题讨论】:

  • r_type 两者都不是呢?
  • 应该抛出异常。
  • 陈述它,并举例说明,否则你需要再写一个 if :>

标签: python design-patterns switch-statement conditional


【解决方案1】:

您可以利用 python 中类为 first class objects 的事实,并使用字典来访问您要创建的类:

classes = {'abc': Abc,    # note: you store the object here
           'def': Def,    #       do not add the calling parenthesis
           'ghi': Ghi,
           'jkl': Jkl}

然后像这样创建类:

new_class = classes[r_type]()  # note: add parenthesis to call the object retreived

如果您的类需要参数,您可以像创建普通类一样放置它们:

new_class = classes[r_type](*args, *kwargs)

【讨论】:

    【解决方案2】:

    dict.get(..)(感谢 Eran Moshe 的编辑):

    classes = {'abc': Abc,
               'def': Def,
               'ghi': Ghi,
               'jkl': Jkl}
    
    
    new_class = classes.get(r_type, lambda: 'Invalid input')()
    

    【讨论】:

    • 你不应该在字典中使用实例化。
    • @EranMoshe 好的,是的,那么还需要一个额外的 if 语句
    • @ReblochonMasque 好点,是的,那么还需要一个额外的 if 语句,如果函数需要参数,你的答案将是最好的
    • 您可以使用 lambda 来完成,让我编辑您的答案
    • @U9-Forward 最后加上 () :> 不能自己编辑。我需要 6 个字符!
    【解决方案3】:

    最好使用dict,因为列表键操作的复杂度是恒定的,它也会处理动态操作。

    cf = {
        'abc': Abc,
        'def': Def,
        'ghi': Ghi,
        'jkl': Jkl,
    }
    r_type = input('value:')
    class_obj = cf.get(r_type, None)
    if class_obj:
       class_obj()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-23
      • 2015-11-01
      相关资源
      最近更新 更多