为什么我的增幅器功能无法正常工作?

时间:2019-04-09 14:43:13

标签: python python-3.x inheritance

我正在尝试将加薪函数应用于类中的变量,但是当我调用该函数时,它给了我一个属性错误,即当我知道该类已经存在并且编写了该类时,该属性不存在它以类似的方式教给我。我给出了两个类以及给我错误的函数调用。

我试图将缺少的属性添加到要从其继承的主类的参数中,并在不同的类上调用它以查看是否有区别。

经过编辑,删除了无需提问的代码。

class Employee:

    pay_raise = 1.04

    def __init__(self, name, eNumber, hDate):
        self.__name = name
        self.__number = eNumber
        self.__date = hDate

    def raise_pay(self):
        self.__payrate = self.__payrate * self.pay_raise

class ProductionWorker(Employee):


    def __init__(self, name, eNumber, hDate, sNumber, pay):

        Employee.__init__(self, name, eNumber, hDate)

        self.__shiftNumber = sNumber
        self.__payrate = pay

    def set_payrate(self, pay):
        self.__payrate = pay

    def get_payrate(self):
        return self.__payrate

#newEmp is object created of ProductionWorker class. Is in tester file in main function.
newEmp.raise_pay()

预期将self .__ payrate乘以pay_raise,并在打印报表中进一步显示新的工资率。当前运行时,输出为“ AttributeError:'ProductionWorker'对象没有属性'_Employee__payrate'”

1 个答案:

答案 0 :(得分:2)

Name Mangling的存在是为了使诸如__payrate之类的变量难以在其定义的类之外访问。甚至该类的子类也无法轻松访问该变量。

按惯例,仅使用一个下划线表示私有属性。然后,名称修饰将不适用,您的私有属性将在子类中访问。 (也可以在其他任何地方访问它们,但是顽皮的用户将要承担风险,但要理解,如果您决定改变班级的内部结构,对于他们来说可能会很不对劲。)

class Employee:

    pay_raise = 1.04

    def __init__(self, name, eNumber, hDate):
        self._name = name
        self._number = eNumber
        self._date = hDate

    def raise_pay(self):
        self._payrate = self._payrate * self.pay_raise

class ProductionWorker(Employee):


    def __init__(self, name, eNumber, hDate, sNumber, pay):

        Employee.__init__(self, name, eNumber, hDate)

        self._shiftNumber = sNumber
        self._payrate = pay

    def set_payrate(self, pay):
        self._payrate = pay

    def get_payrate(self):
        return self._payrate

newEmp = ProductionWorker("Fred", 1, 1, 1, 100)
newEmp.raise_pay()
print(newEmp.get_payrate())

结果:

104.0

奖金样式提示:

  • 如果Employee的方法访问_payrate,则即使必须为其提供占位符值,也应在Employee的__init__中对其进行初始化。
  • 获取器和设置器通常使用@property装饰器来实现,这使得访问公共值更加容易。

class Employee:

    pay_raise = 1.04

    def __init__(self, name, eNumber, hDate):
        self._name = name
        self._number = eNumber
        self._date = hDate

        self._payrate = 0

    @property
    def payrate(self):
        return self._payrate

    @payrate.setter
    def payrate(self, value):
        self._payrate = value

    def raise_pay(self):
        self.payrate *= self.pay_raise

class ProductionWorker(Employee):
    def __init__(self, name, eNumber, hDate, sNumber, pay):

        Employee.__init__(self, name, eNumber, hDate)

        self._shiftNumber = sNumber
        self.payrate = pay


newEmp = ProductionWorker("Fred", 1, 1, 1, 100)
newEmp.raise_pay()
print(newEmp.payrate)

最后,最好不要使用getter或setter,如果他们要做的就是获取并设置私有值而不更改任何其他内容,那会更好。只需使用简单的旧属性即可。

class Employee:

    pay_raise = 1.04

    def __init__(self, name, eNumber, hDate):
        self._name = name
        self._number = eNumber
        self._date = hDate

        self.payrate = 0

    def raise_pay(self):
        self.payrate *= self.pay_raise

class ProductionWorker(Employee):
    def __init__(self, name, eNumber, hDate, sNumber, pay):

        Employee.__init__(self, name, eNumber, hDate)

        self._shiftNumber = sNumber
        self.payrate = pay


newEmp = ProductionWorker("Fred", 1, 1, 1, 100)
newEmp.raise_pay()
print(newEmp.payrate)