构建变量依赖项

2024-10-04 09:24:59 发布

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

我试图用Python构建一些变量依赖关系。例如,如果a = xb = yc = a + b,那么如果a或{}更改了c的值。我知道Python的变量和值是基于标记的,并且一直在尝试使用__setattr__来解决这个问题。由于__setattr__中的循环依赖,我似乎在做这件事时遇到了一些困难。在

考虑一下这个小代码片段:

class DelayComponents(object):
    '''
    Delay Components Class
    '''

    def __init__(self, **delays):
        '''
        Constructor
        '''
        self.prop_delay = round(float(delays['prop_delay']), 2)
        self.trans_delay = round(float(delays['trans_delay']), 2)
        self.proc_delay = round(float(delays['proc_delay']), 2)
        self.queue_delay = round(float(delays['queue_delay']), 2)
        self.delay = (self.prop_delay + self.proc_delay +
                      self.trans_delay + self.queue_delay)

    def __setattr__(self, key, value):
        self.__dict__[key] = value
        if (key in ("prop_delay", "trans_delay",
                    "proc_delay", "queue_delay")):
            self.delay = (self.prop_delay + self.proc_delay +
                      self.trans_delay + self.queue_delay)

这似乎很好地满足了这个目的,但是当我第一次创建一个DelayComponents的对象时,由于__setattr__已经被重写,并且为每个正在创建的值调用,if检查会抛出一个错误,说没有找到剩下的三个变量(这是真的,因为它们还没有被创造出来)。在

如何解决这种依赖关系?在

另外,有没有什么方法可以用dict来实现同样的效果呢?更具体地说,如果这三个变量实际上是dict中的键值对,其中第三个键的值是前两个键的值之和,那么当前两个值中的任何一个发生变化时,是否可以自动更新第三个值?在


Tags: keyselftrans关系queuedefprocfloat
1条回答
网友
1楼 · 发布于 2024-10-04 09:24:59

假设您希望未设置的_delays(在__init____setattr__中)的默认值为零,则可以执行如下操作:

class DelayComponents(object):
    '''
    Delay Components Class
    '''

    ATTRS = ['prop_delay', 'trans_delay', 'proc_delay', 'queue_delay']

    def __init__(self, **delays):
        '''
        Constructor
        '''
        for attr in self.ATTRS:
            setattr(self, attr, round(float(delays.get(attr, 0)), 2))
        # No point in setting delay here - it's already done!

    def __setattr__(self, key, value):
        super(DelayComponents, self).__setattr__(key, value)
        # This avoids directly interacting with the __dict__
        if key in self.ATTRS:
            self.delay = sum(getattr(self, attr, 0) for attr in self.ATTRS)

使用中:

^{pr2}$

如果您想要不同属性的不同默认值,DelayComponents.ATTRS可以是字典{'attribute_name': default_value, ...}。在


一个更简单的替代方法是使delay成为@property,它只根据需要进行计算:

class DelayComponents(object):
    '''
    Delay Components Class
    '''

    ATTRS = ['prop_delay', 'trans_delay', 'proc_delay', 'queue_delay']

    def __init__(self, **delays):
        '''
        Constructor
        '''
        for attr in self.ATTRS:
            setattr(self, attr, round(float(delays.get(attr, 0)), 2))

    @property
    def delay(self):
        return sum(getattr(self, attr, 0) for attr in self.ATTRS)

回答你的子问题:不,用普通的dict是不可能做到这一点的;键的值不会根据计算它们的值的更改而重新评估。在


而且,严肃地说,您当前的docstring没有任何意义;您可以完全忽略它们。它们不提供任何信息,也不符合PEP-257。在

相关问题 更多 >