我正在尝试将加薪函数应用于类中的变量,但是当我调用该函数时,它给了我一个属性错误,即当我知道该类已经存在并且编写了该类时,该属性不存在它以类似的方式教给我。我给出了两个类以及给我错误的函数调用。
我试图将缺少的属性添加到要从其继承的主类的参数中,并在不同的类上调用它以查看是否有区别。
经过编辑,删除了无需提问的代码。
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'”
答案 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
奖金样式提示:
_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)