首页 > 解决方案 > 切换大小写,如字典映射(值 = 方法)

问题描述

由于我是相当新的python,我无法确定以下两种解决方案中的哪一种更有意义,或者根本没有意义。

假设我的抽象对象类看起来像:

class SimpleData(object):

    def __init__(self, data):
        self.__data = data

    def __getData(self):
        return self.__data

    def __setData(self, data):
        self.__data = data

    data = property(__getData, __setData)

    @classmethod
    def create_new(cls, data):
        return cls(data)

我经常需要的这个类的对象(具有“预定义对象有效负载”),我想简单地通过为它们“分配”一个 preset_name 来创建。使用预设名称,我可以重复创建具有预定义有效负载的这些特定对象的新副本。

我可以使用字典:

class PresetDict(object):

    @classmethod
    def get_preset(cls, preset_name):
        return {
            'preset_111': SimpleData.create_new('111'),
            'preset_222': SimpleData.create_new('222'),
            'preset_333': SimpleData.create_new('333')
        }.get(preset_name, None)

或映射方法,使用getattr

class PresetMethod(object):

   @classmethod
   def get_preset(cls, preset_name):
       return getattr(cls, preset_name, lambda: None)()

   @classmethod
   def preset_111(cls):
       return SimpleData.create_new('111')

   @classmethod
   def preset_222(cls):
       return SimpleData.create_new('222')

   @classmethod
   def preset_333(cls):
       return SimpleData.create_new('333')

两种解决方案的作用基本相同:

print(PresetDict.get_preset("preset_111").data)
print(PresetDict.get_preset("preset_333").data)
print(PresetDict.get_preset("not present"))

print(PresetMethod.get_preset("preset_111").data)
print(PresetMethod.get_preset("preset_333").data)
print(PresetMethod.get_preset("not present"))

我非常喜欢字典解决方案,因为它更易于“阅读”、扩展并且将来更易于维护,尤其是对于大量预设。

这是但是:性能很重要。在这里,我完全没有洞察力,这两种解决方案中的哪一种会表现得更好,尤其是在预设列表增加的情况下。尤其是PresetDict.get_preset对我来说,这本字典看起来很“狡猾”。它会在调用时仅创建通过“preset_name”指定的 SimpleData 实例,还是在调用时创建字典中指定的所有可能实例PresetDict.get_preset,然后返回通过“preset_name”指定的实例,然后丢弃所有其他实例。

希望你能在这件事上给我启发。也许您知道我想要实现的可能的改进甚至更好的解决方案?

提前谢谢!

标签: pythondictionarymethodsswitch-statementmapping

解决方案


你是对的,PresetDict.get_preset将创建所有三个对象,然后返回一个。您可以只向SimpleData保存字典的类变量添加一个类变量,因此它只创建一次,并且 get_preset 可以从中返回实例

class SimpleData(object):

    _presets = {
        'preset_111': SimpleData('111'),
        'preset_222': SimpleData('222'),
        'preset_333': SimpleData('333')
    }

    @classmethod
    def get_preset(cls, preset_name):
        return cls._presets.get(preset_name, None)

请注意,这实际上并没有提高效率,它只会使创建常用类变得更加容易。

另见functools.lru_cache


推荐阅读