2013-06-14 3 views
0

다음과 같이 급여 구성 요소를 계산하는 클래스가 있습니다.데코레이터에서 인스턴스 변수를 설정하는 방법은 무엇입니까?

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 
    } 

각 수당을 계산하기 전에 모든 수당의 총액이 총 지불액, 즉 총 급여를 초과하지 않는지 확인해야합니다. 나는 각 수당 계산 방법을 감싸고 위의 요구 사항을 말하는 데코레이터를 작성했습니다. 예 :

* an employee having a salary of Rs.6700 
* basic = 6,600 (according to slab) 
* dearnessAllowance = 100 (cos 20% of basic is more than remaining amount) 
* houseRentAllowance = 0.0 (cos 40% of basic is more than remaining amount) 

하지만 불행히도 작동하지 않았습니다. 첫 번째 수당은 올바르게 계산되지만 다른 수당에는 첫 번째 수당과 동일한 값이 부여됩니다. 즉 houseRentAllowance는 위에 제공된 것처럼 0.0 대신 100을 갖습니다.

내가 찾은 문제는 내가 작동하지 않습니다 클래스의 변수를 설정하기 위해 애 쓰고 장식 코드

instance.remainingAmount = instance.remainingAmount - allowanceToCheck 

의 라인입니다.

이 문제를 해결할 수있는 방법이 있습니까?

+0

매우 이상합니다. 그것은 저에게 효과적입니다. 당신은 정말로 클래스 또는 인스턴스 변수의 변수를 설정하려고합니까? – oleg

+0

안녕하세요. 나는 그것의 인스턴스 변수를 믿는다. –

+3

이것은 실제 코드가 아닙니다. ('class'에 대한'Class'). 문제를 보여주는 실행 가능한 예제를 게시하십시오. –

답변

4

Salary.basic은 재산으로, Salary.basic()은 부작용이 있습니다. 따라서 다른 함수가 self.basic을 참조 할 때마다 self.RemainingAmount을 다시 계산하고 원래 값인 self.grossPay - basic으로 다시 설정합니다.

이러한 종류의 부작용이있는 속성은 입니다. 잘못된 디자인입니다. 나는 왜 당신이 지금 볼 수 있기를 바랍니다. 이 문제를 해결 한 후에도 다른 속성으로 다른 순서로 액세스하면 다른 결과를 얻을 수 있습니다. 속성 접근자는 내구성이있는 부작용이 없어야합니다. 더 일반적으로 : 세터를 설정해야하며 getters가 가져와야합니다. 속성 은 간단한 변수와 마찬가지로처럼 보이므로 그에 따라 행동해야합니다. 그렇지 않으면 코드를 다시 이해하거나 디버깅 할 수 없습니다.

+0

그래, 그건 내가 추측 한 문제 였어 야 했어. 내가 한번 살펴보고 계속 게시하도록하겠습니다. 시간과 도움에 감사드립니다. –

+0

'기본'을 일반 변수로 만드는 것은이 버그를 수정해야하지만 나머지 속성은 삭제해야합니다. 그것들을 행동으로 바꾸십시오 ('deductHouseRentAllowance()'등) – alexis

관련 문제