Почему моя функция мутатора работает неправильно? - PullRequest
0 голосов
/ 09 апреля 2019

Я пытаюсь применить функцию повышения заработной платы к переменной, которая находится в классе, но когда я вызываю функцию, она выдает ошибку атрибута, говорящую, что ее нет в указанном классе, когда я знаю, что она есть, и я написала это так же, как меня учили. Я дал два класса и вызов функции, которая дает мне ошибку.

Я попытался добавить отсутствующий атрибут к параметрам основного класса, от которого наследуется, а также вызвать его в разных классах, чтобы увидеть, имеет ли это значение.

Отредактировано для удаления кода, ненужного для вопроса.

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()

Ожидается умножение собственной ставки .__ на pay_raise и далее в отчете о печати показывает новую ставку оплаты. При запуске, как это в настоящее время, мне выдается «AttributeError: у объекта ProductionWorker нет атрибута _Employee__payrate»

1 Ответ

2 голосов
/ 09 апреля 2019

Имя искажения существует для того, чтобы сделать переменные с именами, такими как __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, вам следует инициализировать его в __init__ Employee, даже еслиВы должны задать ему значение-заполнитель.
  • Получатели и установщики обычно реализуются с использованием декоратора @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)

Наконец, вам может быть лучше вообще не использовать геттер или сеттер, если все, что они собираются сделать, - это получить и установить приватное значение, не меняя ничего другого.Просто используйте простой старый атрибут.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...