2

我在设计适用于对象组合的(Python)开关模式时遇到问题。更具体地说,我想创建一个将“entity_id”作为参数(+其他相关参数)的函数,为它创建一个对象和匹配的组件(可能使用附加参数)。这是一个玩具示例

class Entity:
    def __init__(self,name,animal=None,item=None):
    self.name = name

class Animal: # Animal component
    def __init__(self,legs):
    self.legs = legs

class Item: # Item component
    def __init__(self,quantity):
    self.quantity = quantity

我想要类似的东西:

def place_entity(entity_id,quantity=1):

switch (entity_id):
case 'emu':
    animal_component = Animal(2)
    ent = Entity('Emu', animal_component)
    break

case 'apple':
    item_component = Item(quantity)
    ent = Entity('Apple(s)', item_component )
    break

return(ent)

使用 for 循环和 if 语句很容易生成上述内容,但是有更好的方法吗?应该很容易

  1. 添加新类型的实体(香蕉、钉子、鲨鱼等),
  2. 添加新的组件(例如可食用的,它告诉实体是否是可食用的以及它包含多少卡路里),

无需在太多地方更改代码。请注意,组件有时需要额外的参数(在函数的输入中给出)。

我已经看到 switch 语句被字典取代,但我的实现(如下)结果很糟糕。添加另一个组件需要向每个实体函数添加代码!

我也不知道如何以优雅的方式将参数传递给组件。附加参数在此实现中不起作用。也就是说,如果我想创建一个苹果的实体(一批)(假设数量 = 5),我将不得不修改每种类型的实体函数以接受数量参数(即使它不使用它),或者修改创建实体后的数量(这并不聪明,因为如果使用 if 语句,那么还不如使用 for loop+if 语句)。

def create_entity(entity_id,quantity=None):

    def emu():
        animal_component = Animal(2)
        entity_data = {'name':'Emu','animal_component':animal_component,
                   'item_component':None}
        return(entity_data)

    def apple(quantity=1):
        item_component = Item(quantity)
        entity_data = {'name':'Apple(s)','animal_component':None,
                   'item_component':item_component}
        return(entity_data)

entity_dict = {'emu':emu,'apple':apple}

entity_data = entity_dict[entity_id]()

ent = Entity(entity_data['name'], animal=entity_data['animal_component'],
             item=entity_data['item_component'])
return(ent)
4

1 回答 1

0

您可以使用此函数定义模拟 switch 语句:

def switch(v): yield lambda *c: v in c

用法将非常接近您正在寻找的内容:

for case in switch (entity_id):

    if case('emu'):
        animal_component = Animal(2)
        ent = Entity('Emu', animal_component)
        break

    if case('apple'):
        item_component = Item(quantity)
        ent = Entity('Apple(s)', item_component )
        break
于 2021-01-15T02:54:31.337 回答