如何动态调用函数

2024-03-28 03:43:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类,其中包含多个列表作为属性,以及多个add方法,用于根据对象的类型将对象附加到特定列表中。你知道吗

我的代码读取包含对象类型的csv文件,以便创建并将其添加到我的购物车中。 我的问题是,我正在测试对象类型以使用if elif语法调用正确的'add'函数,但这不是很好,也很难维护。你知道吗

例如

import csv


class my_item():
    def __init__(self, name):
        self.name = name


class fruit(my_item):
    pass


class vegetable(my_item):
    pass


class meat(my_item):
    pass


class fish(my_item):
    pass


class shopping_cart():
    def __init__(self):
        self.fruits = []
        self.vegetables = []
        self.meat = []
        self.fish = []

    def add_fruit(self, o):
        self.fruits.append(o)

    def add_vegetable(self, o):
        self.vegetables.append(o)

    def add_meat(self, o):
        self.meat.append(o)

    def add_fish(self, o):
        self.fish.append(o)

    def __str__(self):
        msg = ""
        msg += "{:<25}= {:<5}\n".format('Total', str(len(self.fruits) + len(self.vegetables) + len(self.meat) + len(self.fish)))
        for attrname in vars(self):
            value = getattr(self, attrname)
            if isinstance(value, list):
                msg += "  {:<23}= {:<5}\n".format(attrname, len(value))
        return msg

def main():
    input_f = 'input.csv'
    my_cart = shopping_cart()
    with open(input_f, 'r') as i:
        rows = csv.reader(i, delimiter=';')
        for row in rows:
            item = globals()[row[0]](row[1])
            if item.__class__.__name__ == 'fruit':
                my_cart.add_fruit(item)
            elif item.__class__.__name__ == 'vegetable':
                my_cart.add_vegetable(item)
            elif item.__class__.__name__ == 'meat':
                my_cart.add_meat(item)
            else:
                my_cart.add_fish(item)
    print (my_cart)

if __name__ == '__main__':
    main()

你看到了if elif块的替代品吗?你知道吗

谢谢你的反馈。你知道吗


Tags: csv对象nameselfaddlenifmy
2条回答

当然,您只需要动态地创建函数名并调用它。 小心,只有当我的购物车有add_{{ item name }}方法时,这才有效。你知道吗

def main():
    input_f = 'input.csv'
    my_cart = shopping_cart()
    with open(input_f, 'r') as i:
        rows = csv.reader(i, delimiter=';')
        for row in rows:
            item = globals()[row[0]](row[1])
            item_name = item.__class__.__name__
            item_add_func_name = 'add_{}'.format(item_name)
            item_add_func = getattr(my_cart, item_add_func_name, None)
            if item_add_func and callable(item_add_func):
                item_add_func(item)
            # if item.__class__.__name__ == 'fruit':
            #     my_cart.add_fruit(item)
            # elif item.__class__.__name__ == 'vegetable':
            #     my_cart.add_vegetable(item)
            # elif item.__class__.__name__ == 'meat':
            #     my_cart.add_meat(item)
            # else:
            #     my_cart.add_fish(item)

    print (my_cart)

我可以建议一个更简单的课堂设计吗。你知道吗

  • my_item保持原样,其他类fruit, vegetable etc。已删除

  • shopping_cart进行修改,使得self.items是一个字典,其中键是项的名称fruit, vegetables,值是这些项的列表

那么代码可能如下所示

import csv
from collections import defaultdict


class my_item:
    def __init__(self, name):
        self.name = name


class shopping_cart:

    def __init__(self):
        #Dictionary to hold items
        self.items = defaultdict(list)

    def add_item(self, type, name):

        #Increment the count of the item by 1
        self.items[type].append(name)

    def __str__(self):

        #Iterate through the dictionary and print all key/value pairs
        msg = ""
        for k,v in self.items.items():
            msg += ' {}: {} '.format(k, v)
        return msg.strip()


sc = shopping_cart()
sc.add_item('fruit', 'pomme')
sc.add_item('vegetable', 'dinde')
sc.add_item('meat', 'carotte')
sc.add_item('fish', 'saumon')

print(sc)

输出看起来像

fruit: ['pomme']  vegetable: ['dinde']  meat: ['carotte']  fish: ['saumon']

相关问题 更多 >