【问题标题】:Implementing rules in a class python在类python中实现规则
【发布时间】:2021-06-09 19:54:46
【问题描述】:

我一直坚持在类中应用规则,例如如果存在某些规则则强制更改某些值等等。但是我无法将规则传递给班级。这是我的代码,我需要什么:

class Item: 
    valid_item_dict = {"a":20, "b":30, "c":40, "d":50}
    def __init__(self, item_id):
        self.item_id = item_id
        self.item_cost = Item.valid_item_dict.get(self.item_id)

class checks:
    def __init__(self):
        self.content = list()
        
    def cheque(self, item):
        self.content.append(item)
        
    def totals(self):
        self.total = sum([self.item_counter().get(itm)*Item.valid_item_dict.get(itm) for\
                          itm in list(self.item_counter().keys())])
        return self.total
    
    def item_counter(self):
        self.item_count_list = [itms.item_id for itms in self.content]
        self.item_count_dict = dict((item, self.item_count_list.count(item)) for item in
                                     self.item_count_list)
        return self.item_count_dict

# Adding items to the list
item1 = Item("a")
item2 = Item("a")
item3 = Item("a")
item4 = Item("b")

# instatiance of class
cx = checks()
cx.cheque(item1)
cx.cheque(item2)
cx.cheque(item3)
cx.cheque(item4)

cx.totals()
>>> 90 (20*3 (from a) + 1*30 (from b))

在正常情况下,这可以正常工作,但我需要添加大量规则,并且我之前曾考虑在“检查”类的 totals 方法中添加 if-else 规则。但是他们是添加这些规则的更通用的方式。规则类似于如果我们有 3 种产品 a,那么“a”的值从 20 减少到 10。 我确实解决了这个问题并尝试使用它,但任何帮助都会很棒。 (Python how to to make set of rules for each class in a game)

【问题讨论】:

    标签: python python-3.x rules rule-engine


    【解决方案1】:

    您可能希望使用更直接的循环来实现这些规则并使您的代码更清晰。我发现维护复杂的逻辑比尝试编写 1 行结果更容易:

     from collections import Counter, namedtuple
     
     Rule = namedtuple("Rule", ["threshold", "newvalue"])
     """rule: if count is greater than or equal to threshold, replace with newvalue"""
    
     
     class Item:
        rules = {'a': Rule(3, 10)}
    
        ...
    
    class checks:
    
        ...
    
        def totals(self):
            counts = Counter(self.content)
            self.total = 0
            for count in counts:
                value = Item.valid_item_dict[count]
                rule = Item.rules.get(count, Rule(0, value))
                if counts[count] >= rule.threshold:
                    value = rule.newvalue
                self.total += value*counts[count]
    
            return self.total
           
    

    我假设您希望样本的结果为 60 而不是 90。

    【讨论】:

    • 是的,希望结果为 60。我尝试了在“value = Item.valid_item_dict[count]”行中给出“KeyError: <__main__.item object at>”的代码。但是,我了解您在此处尝试将有效项目字典中的值更新为基于规则的新值。然而,它是通用的吗?我的意思是如何实施规则,例如对于每个“d”作为一个项目,您将“c”添加为免费或每 5 个 b 计数,只有 3 个将计入总数。我可以用这种方法做到这一点吗?感谢您的回复,并为延迟回复道歉。
    • 对不起。我应该指出这是一个草图,我没有充分测试它。如果您想要数学规则,那么您的规则集可以从运算符模块中提取并包含它(即{"a": (operator.gte, 3, 10)}),然后更新代码以引用规则中的运算符。对于更复杂的规则,您需要更复杂的可解析语言或代码。 (即{"b": (gte, 5, "add c")},但您需要考虑这些值并正确处理它们)。您应该能够以类似的方式对其进行概括。
    • 谢谢@Josh English。使用运算符和使用解析复杂规则来更新值的整个想法让它工作。将进一步改进它,但它现在已经足够概括了。谢谢。
    猜你喜欢
    • 2010-10-02
    • 2016-02-16
    • 1970-01-01
    • 2012-04-16
    • 2019-11-04
    • 2016-06-09
    • 1970-01-01
    • 2018-01-28
    • 2018-11-29
    相关资源
    最近更新 更多