【问题标题】:Implement logic between different instances of the same class在同一类的不同实例之间实现逻辑
【发布时间】:2019-07-17 06:47:45
【问题描述】:

我想在同一个类的不同实例之间实现一些逻辑,但我不知道如何正确地做到这一点。审查和建议都是必需的。

最好从一个例子开始。假设我有一个班级foo。此类中有三个属性 - idgroupnitem

要实现的逻辑是foo的实例如果在同一组下应该有相同数量的项目(即nitem)。

有些人可能已经注意到我已经在实例之间实现了一段逻辑,它通过foo._id 计算实例的数量。但是你也可以很容易地理解这种方法是多么的幼稚。如果您创建三个foo 实例并删除中间实例。最后一个实例仍然有id=3

class foo(object):
    _id = 0
    def __init__(self, group, nitem):
        foo._id += 1
        self.id = foo._id
        self.group = group
        self.nitem = nitem

if __name__ == "__main__":
    a = foo(1, 100)
    b = foo(2, 10) #no error. Different groups can have different nitem.
    c = foo(1, 10) # I want this to raise error.Same groups can't have different nitem.

【问题讨论】:

    标签: python python-3.x class oop


    【解决方案1】:

    覆盖 __new__ 以在对象实例化时执行检查:

    https://docs.python.org/3/reference/datamodel.html#object.new

    from typing import Any
    
    
    class foo(object):
        _groups = {}
    
        def __new__(cls, group, nitem) -> Any:
            if group not in cls._groups:
                cls._groups[group] = nitem
            if cls._groups[group] == nitem:
                return super().__new__(cls)
            raise ValueError('mismatched group and nitems')
    
        def __init__(self, group, nitem):
            self.group = group
            self.nitem = nitem
    
    
    if __name__ == "__main__":
        a = foo(1, 100)
        b = foo(2, 10)
        c = foo(2, 100)
    
    

    输出:

    Traceback (most recent call last):
      File "app.py", line 23, in <module>
        c = foo(2, 100)
      File "app.py", line 12, in __new__
        raise ValueError('mismatched group and nitems')
    ValueError: mismatched group and nitems
    

    创建c时会报错

    【讨论】:

    • 如果一个实例的引用计数为零并且被Python的垃圾收集从内存中擦除,我该如何更新cls._groups
    【解决方案2】:

    由于使用特定nitem 编号定义的组数量有限,您可以简单地使用字典,其中键是组名称,项目是组允许拥有的nitem 的编号。然后在构造函数中,您可以简单地利用字典为组对应的nitem 分配一个默认值。

    一个例子是这样的:

    group_dict = {"students": 5,
                  "teachers": 10}
    
    class foo(object):
        def __init__(self, group, nitem=group_dict[str(group)]):
            self.group = group
            self.nitem = nitem
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-15
      • 1970-01-01
      • 2019-01-30
      • 1970-01-01
      • 2020-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多