Инкапсуляция в Python - PullRequest
       27

Инкапсуляция в Python

0 голосов
/ 25 января 2020

Рассмотрим класс Employee

class Employee:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary

emp_obj = Employee('Sam', 50000)
print(emp_obj.name, emp_obj.salary)

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

class Employee:
    def __init__(self, name, salary):
        self.name = name
        self.__salary = salary

    @property
    def salary(self):
        return self.__salary

    @salary.setter
    def salary(self, salary):
        self.__salary = salary

    def getSalary(self):
        return 'The Salary is {0}' .format(self.salary)

emp_obj = Employee('Sam', 50000)
print(emp_obj.name, emp_obj.salary)
print(emp_obj.getSalary())

Я не вижу значительной разницы.

Поэтому я снова изменил код:

class Employee:
    def __init__(self, name):
        self.name = name
        #self.__salary = salary

    def setSalary(self, salary):
        self.__salary = salary

    def getSalary():
        return salary

emp_obj = Employee('Sam')
emp_obj.setSalary(50000)
print(emp_obj.name)
print(emp_obj.getSalary)

Вывод, который я получил, был:

Sam
<bound method Employee.getSalary of <__main__.Employee object at 0x0000019E1B961A58>>

Что означает вышеприведенный вывод? Ясно, что мой код не работал должным образом. Я попытался установить зарплату, передав в качестве аргумента значение зарплаты. Пожалуйста, укажите ошибку и способ ее решения.

У меня также есть еще одно сомнение - что представляют или передают Python функции (методы), которые начинаются и заканчиваются символами подчеркивания?

def __init__(self):

Приведенная выше команда используется для инициализации конструктора в Python, которая вызывается по умолчанию при создании объекта класса.

Я использую Python 3.6.5.

Код был изменен согласно @ShadowRanger:

print(emp_obj.getSalary())

Затем я получил следующий вывод с ошибкой:

Sam
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-f115117b2a1c> in <module>()
     13 emp_obj.setSalary(50000)
     14 print(emp_obj.name)
---> 15 print(emp_obj.getSalary())

TypeError: getSalary() takes 0 positional arguments but 1 was given

1 Ответ

1 голос
/ 25 января 2020

Чтобы устранить проблему с оператором печати, вы можете сделать следующее:

def getSalary(self):
   return ....

Вы забыли self, который требуется для каждого метода экземпляра.

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

class Person:
    def __init__(self):
        self._ssn = None

    @property
    def ssn(self):
        return f'{self._ssn[:3]}-XX-XXXX'

здесь все вызывающие абоненты увидят скрытую версию SSN при доступе к нему с помощью свойства.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...