如何在decorator中设置实例变量?

2024-06-26 00:12:13 发布

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

我有一个计算薪资组成的类,如下所示。在

def normalize(func):
    from functools import wraps

    @wraps(func)
    def wrapper(instance, *args, **kwargs):
        allowanceToCheck = func(instance)
        if instance.remainingAmount <= 0:
            allowanceToCheck = 0.0
        elif allowanceToCheck > instance.remainingAmount:
            allowanceToCheck = instance.remainingAmount
        instance.remainingAmount = instance.remainingAmount - allowanceToCheck
        return allowanceToCheck
    return wrapper

class SalaryBreakUpRule(object):
    grossPay = 0.0
    remainingAmount = 0.0

    @property
    def basic(self):
     # calculates the basic pay according to predefined salary slabs.
     basic = 6600 # Defaulting to 6600 for now.
     self.remainingAmount = self.grossPay - basic
     return basic

    @property
    @normalize
    def dearnessAllowance(self):
      return self.basic * 0.2

    @property
    @normalize
    def houseRentAllowance(self):
      return self.basic * 0.4

   def calculateBreakUps(self, value = 0.0):
    self.grossPay = value
    return {
        'basic' : self.basic,
        'da' : self.dearnessAllowance,
        'hra' : self.houseRentAllowance
    }

在计算每个津贴之前,我需要检查所有津贴的总额是否不超过我的工资总额。我写了一个装饰程序,它包装了每一种津贴计算方法,并完成了上述要求。例如

^{pr2}$

但不幸的是它没有起作用。首次免税额计算正确,但所有其他免税额与首次免税额相同。i、 房屋租赁津贴为100,而不是上述的0.0。在

我发现的问题是,代码行

instance.remainingAmount = instance.remainingAmount - allowanceToCheck

在decorator中,我试图设置类的一个变量不起作用。在

我有办法解决这个问题吗?在


Tags: instanceselfreturnbasicdefpropertywrapper津贴
1条回答
网友
1楼 · 发布于 2024-06-26 00:12:13

您已将Salary.basic设置为属性,Salary.basic()有副作用!所以每次其他函数引用self.basic,它都会重新计算并将self.RemainingAmount重置为其原始值self.grossPay - basic。在

具有这种副作用的特性是不良设计。我希望你现在明白原因了。即使您修复了这个问题,以不同的顺序访问其他属性也会得到不同的结果。属性访问器不应该有持久的副作用。更一般地说:Setters必须设置,getter必须得到。属性看起来就像简单的变量,因此它们必须相应地执行,否则您将永远无法理解或调试代码。在

相关问题 更多 >