Что такое приватный метод в python
Перейти к содержимому

Что такое приватный метод в python

  • автор:

Что такое приватный метод в python

Encapsulation is one of the fundamental concepts in object-oriented programming (OOP) in Python. It describes the idea of wrapping data and the methods that work on data within one unit. This puts restrictions on accessing variables and methods directly and can prevent the accidental modification of data. A class is an example of encapsulation as it encapsulates all the data that is member functions, variables, etc. Now, there can be some scenarios in which we need to put restrictions on some methods of the class so that they can neither be accessed outside the class nor by any subclasses. To implement this private methods come into play.

P rivate functions in Python

Consider a real-life example, a car engine, which is made up of many parts like spark plugs, valves, pistons, etc. No user uses these parts directly, rather they just know how to use the parts which use them. This is what private methods are used for. It is used to hide the inner functionality of any class from the outside world. Private methods are those methods that should neither be accessed outside the class nor by any base class. In Python, there is no existence of Private methods that cannot be accessed except inside a class. However, to define a private method prefix the member name with the double underscore__”. Note: The __init__ method is a constructor and runs as soon as an object of a class is instantiated.

Private Methods in Python

Private Methods in Python

Encapsulation is one of the important concepts in object-oriented programming. It refers to the idea of wrapping the data and the methods that work within one unit or class. Therefore, it helps to put restrictions on accessing the methods and variables directly to prevent the modification of the data. There are many access modifiers that help us with such restrictions and avoid other classes to use the methods and variables accordingly. In this article, let us study one of these access modifiers named Private in detail with all the necessary operations and examples. Let’s get started!

What are Private Methods in Python?

A private method is an access modifier used in a class that can only be called from inside the class where it is defined. It means that you cannot access or call the methods defined under private class from outside.

Consider a real-life example as a car engine. The car engine is made up of various parts like valves, sparks, pistons, etc. No user can make use of these parts by themselves. The same situation is with a private method which hides the inner functionality of the class from the outside world.

Remember that even the base class cannot access the methods of private class. In python programming, there are no private methods that cannot be accessed except inside the class. To define the private method, you have to prefix the member name with a double underscore(__).

The __init__() Method

The fundamental private method in Python is the __init__() method which is used as a class constructor. This method is called when you initiate the class object depending on the method’s argument.

Check the example below where we declare a class “Fruit” with two attributed and an __init__() method:

Now to access the __init__() method outside the class, we would need to access it from the object of its class after instantiating it.

For instance, another file in the same directory create an instance of class “fruit” and call the constructor using the class name.

Remember that to import the classes from another file into the current file you have to use the “sys.path.append()” method with the string path directory of the class.

As the in-built method is been discussed, let us move to understand the actual implementation of your own private methods.

Defining Private Methods and Attributes

To define a private attribute or method in python, you have to just prefix the name with a single underscore(_).

For example, here we have a class named «Class» and the __init__ method is defined with one attribute “var” with its value equals 2. Later the get_var method returns the value of the «var» attribute by defining a function as shown below:

Now, we will rewrite the above example to make “var” and “get_var” as private attributed.

When we try to access this method the output of the program will be 2. You must be wondering that how is this possible because we cannot access the private attribute and methods, right?

In python, private access to private methods and attributes is not enforced. Therefore, when attributes start with a single underscore, that is just a convention and not an enforced decision.

Python does not support encapsulation but that doesn’t mean you must access attributed and methods that are prefixed with an underscore. Moreover, if you are designing your own library or class, you are recommended to use the variable names with a single underscore as a prefix to specify that attributes and methods shouldn’t be accessed.

This was all about the names with a single underscore as a prefix, but what about two underscores or no trailing underscores. Let’s discuss about that now.

Name Mangling

Let us define the attribute “var” and “get_var” from the above example but using double underscore.

For Example:

When you run the above program, an error will be generated which suggests «no such attribute “__var” is available» even though we have defined the value of the “var” attribute.

This error can be solved by replacing the class name before the name of the attribute. For example, attribute “var” becomes “_Class__var” for the above class. Similarly, “get_var” becomes “_Class__get_var”.

This change in the behaviour of the attribute is called the name mangling. Therefore, python provides a special concept that can be used to call the private method from outside the class known as the name mangling.

Remember that accessing the variables of private class from outside is harder using name mangling, but still, it is accessible through “_Class__var”.

Many developers and programmers make mistakes using the name mangling technique to denote the private attributes and methods of the class. But it should be taken care of that denoting private methods and attributes is not the primary function of name mangling.

Conclusion

Encapsulation is the most fundamental concept of python programming which provides multiple access modifiers to protect our class and methods from the outside world. The private method is one of those access modifiers which is highly used by every developer to protect their codes and data from others. It is always recommended to learn and understand private methods when you are keen to develop your own class or libraries in python programming.

Приватные методы без нижнего подчеркивания и интерфейсы в Python

Привет, Habr. Недавно угорел по дизайну — модификаторам доступа и интерфейсам, потом перенес это на язык программирования Python. Прошу под кат — делюсь результатами и как это работает. Для заинтересовавшихся в конце статьи есть ссылка на проект на Github.

Модификаторы доступа

Модификаторы доступы ограничивают доступ объектам — к методам их класса, или дочерним классам — к методам их класса-родителя. Использование модификаторов доступа помогает сокрыть данные в классе таким образом, чтобы никто снаружи не смог помешать работе этого класса.

private (приватные) методы доступны только внутри класса, protected (защищенные) — внутри класса и в дочерних классах.

Как реализованы приватные и защищенные методы в Python

Спойлер — на уровне соглашения, что взрослые люди просто не будут их вызывать вне класса. Перед приватными методами нужно писать двойное нижнее подчеркивание, перед защищенными одно. И вы по-прежнему можете обратиться к методам, несмотря на их «ограниченный» доступ.

Можно определить следующие минусы:

  • Если бы метод _start_engine обновлял какие-то переменные класса или сохранял состояние, а не просто возвращал «тупой расчет», вы могли что-то поломать для будущей работы с классом. Вы не позволяете себе что-то чинить в моторе вашей машины, потому что тогда никуда не поедете, верно?
  • Вытекающий пункт из предыдущего — чтобы убедиться, что можно «безопасно» (вызов метода не навредит самому классу) использовать защищенный метод — нужно заглянуть в его код и потратить время.
  • Авторы библиотек рассчитывают, что никто не пользуется защищенными и приватными методами классов, которые вы используете в своих проектах. Поэтому могут в любой релиз изменить его реализацию (которая на публичные методы не повлияет из-за обратной совместимости, но вы — пострадаете).
  • Автор класса, ваш коллега, рассчитывает, что вы не увеличите технический долг проекта, использовав защищенный или приватный метод вне созданного им класса. Ведь тому, кто будет его (приватный метод класса) рефакторить или изменять, придется убедиться (например, через тесты), что его изменения не поломают ваш код. А если поломают — ему нужно будет тратить время на то, чтобы решить эту проблему (костылем, потому что надо на вчера).
  • Возможно, вы следите за тем, чтобы другие программисты не использовали защищенные или приватные методам на code review и «бьете за это по рукам», значит — тратите время.

Как реализовать защищенные методы с помощью библиотеки

Попытавшись вызвать метод start_engine за пределами класса, вы получите следующую ошибку (метод недоступен согласно политике доступа):

  • Вам не надо использовать некрасивое (субъективно) нижнее или двойное нижнее подчеркивание.
  • Получаете красивый (субъективно) метод внедрения модификаторов доступа в код — декораторы private и protected.
  • Перекладываете ответственность с человека на интерпретатор.

    Декоратор private или protected — самый «высоко» расположенный декоратор, срабатывает до метода класса, которому объявили приватный или защищенный модификатор доступа.

Интерфейсы

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

Пример

Имеем класс User, который использует объект storage, чтобы создать нового пользователя.

Сохранять пользователя можно в базу данных, используя DatabaseStorage.create_with_name.

Сохранять пользователя можно в файлы, используя FileStorage.create_with_name.

За счет того, что сигнатуры методов create_with_name (название, аргументы) у классов одинаковые — классу User не стоит волноваться какой объект ему подставили, если у обоих одинаковые методы. Это может быть достигнуто если классы FileStorage и DatabaseStorage реализуют одинаковый интерфейс (то есть связаны контрактом определить какой-то метод с логикой внутри).

Как работать с интерфейсами с помощью библиотеки

Если класс имплементирует интерфейс, класс должен содержать все методы интерфейса. В примере ниже интерфейс «HumanInterface» содержит метод «eat», а класс «Human» его имплементирует, но не реализовывает метод «eat».

Скрипт завершит работу со следующей ошибкой:

Если класс имплементирует интерфейс, класс должен содержать все методы интерфейса, включая все входящие аргументы. В примере ниже интерфейс «HumanInterface» содержит метод «eat», который на вход принимает 4 аргумента, а класс «Human» его имплементирует, но реализовывает метод «eat» только с 1 аргументом.

Скрипт завершит работу со следующей ошибкой:

Если класс имплементирует интерфейс, класс должен содержать все методы интерфейса, включая входящие аргументы и модификаторы доступа. В примере ниже интерфейс «HumanInterface» содержит приватный метод «eat», а класс «Human» его имплементирует, но не реализовывает приватный модификатор доступа к методу «eat».

Скрипт завершит работу со следующей ошибкой:

Класс может имплементировать несколько (количество неограниченно) интерфейсов. Если класс имплементирует несколько интерфейсов, класс должен содержать все методы всех интерфейсов, включая входящие аргументы и модификаторы доступа. В примере ниже класс «Human» реализовывает метод «eat» интерфейса «HumanBasicsInterface», но не реализовывает метод «love» интерфейса «HumanSoulInterface».

Скрипт завершит работу со следующей ошибкой:

Киллер фича — метод интерфейса может «заявить» какие ошибки должен «бросить» метод класса, который его имплементирует. В примере ниже «заявлено», что метод «love» интерфейса «HumanInterface» должен выбрасывать исключение «HumanDoesNotExistError» и
«HumanAlreadyInLoveError», но метод «love» класса «Human» не «бросает» одно из них.

Private Methods And Functions In Python With Access Modifiers

Weekly Python

When working with object-oriented programming languages we sometimes need to keep a piece of code from being executed arbitrarily from anywhere else in the system. To solve this problem, the concept of access modifiers were introduced into early language design.

In languages like C++, Java, or C# we can use the reserved keywords public, protected, or private to mark the members of a class. Python does have all three access modifiers, but it doesn’t use keywords to mark a member. Instead, Python uses underscores _ to mark a function or variable as protected or private.

However, Python does not actually enforce these access modifiers like other languages. Instead, it uses name mangling to obfuscate the function or variable and make it harder to find. In other words, if you really wanted to access it, you could. The only thing forcing this convention is you as the programmer.

Protecting Module Functions

When working with module wide functions, sometimes we don’t want our function to be usable to anyone that imports the module. One way to accomplish that is to put one or two underscores in front of the function name.

For example, if we define a module file random_module.py :

We can then import that module in the interpreter and try to use it:

This also works if we use from random_module import * so our private function can stay that way.

Class Private Methods and Variables

Sometimes we want to put restrictions on our class members where they can’t be accessed outside the class or even from any subclasses. In those cases, we can declare a variable or method as private using the __ double underscore.

If we instantiate this class and attempt to access the variable or method:

We can see that neither attribute is available for us to use. But can we access them if we subclass?

Now if we import this:

The error looks slightly different but it is still an error! As I mentioned above, Python internally uses name mangling to actually hide the attributes. If a variable is protected, instead of private, it will be moved into a reference _CLASS_VARIABLE to make it less accessible. But if you know that pattern, you can actually reach in and use any protected variable from anywhere.

Class Protected Methods and Variables

Ok, so we saw in the last example that if the variable or method is only protected we should be able to access them from a subclass. So, how do we define a protected attribute? The answer is to use a _ single underscore in front of the name.

Now we can create a subclass and check it out!

And if we load this into the interpreter:

And with that, you now know how to encapsulate and obfuscate your functions and variables inside Python using Access Modifiers.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *