Статьи

ООП в Python – часть 1

Что такое ООП (объектно-ориентированное программирование)?

Объектно-ориентированное программирование — это парадигма программирования, которая создает «объекты» на этапе программирования, пытаясь смоделировать сущности из проблемы, которую необходимо решить.

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

Когда мы обсуждаем ООП, нужно обсудить 3 ключевых момента (также называемых тремя столпами ООП):

  • Инкапсуляция  — означает блокирование в одном блоке данных и методов, которые взаимодействуют с данными в классе. Это полезно, потому что внутренняя структура модели может быть изменена только с помощью методов, которые она предоставляет, другие сущности (объекты) не могут изменять внутреннее состояние другой.
  • Наследование  — обычно, когда мы строим модели о реальных проблемах, мы получаем большие иерархии объектов. Эти модели (классы) имеют отношения между собой. Отношение  «есть»  в иерархии модели реализуется с использованием наследования внутри ООП, это означает, что функции, существующие в одной модели (или объекте), также будут существовать в производной.
    Пример. Предположим, что вы хотите создать свой собственный интернет-магазин и продавать гаджеты. Гаджеты имеют такие свойства, как емкость аккумулятора, вес, объем памяти, операционная система и т. Д. Если вы хотите продать планшет в своем интернет-магазине, вы можете сказать, что планшет — это гаджети при реализации их в коде вы можете использовать наследование для передачи всех атрибутов и функций класса Gadget в класс Tablet.
  • Полиморфизм  — это возможность объекта вести себя по-другому в зависимости от того, какой у него подтип. Полиморфизм связан с наследованием.
    Пример. Предположим, вы хотите продавать умные часы и в своем интернет-магазине.  Смарт Часы является Gadget, Все гаджеты могут быть перезапущены, это может быть операция (или метод) гаджета. Поскольку оба (планшет и Smart Watch) наследуются от гаджета (у них есть взаимосвязь), они также наследуют операцию перезапуска, НО операция перезапуска на Smart Watch отличается от операции на планшете. Итак, если мы перезапускаем и Smart Watch, и планшет, мы использовали общую операцию (restart), но каждая из моделей выполняет операцию по-своему, в основном, глядя на нее с более абстрактного уровня, мы имеем 2 гаджета, которые имеют полиморфное поведение (в зависимости от их типа) при выполнении операции перезапуска.

Что такое Python?

Python  — это динамический типизированный универсальный язык программирования высокого уровня. Он был разработан и разработан  Гвидо ван Россумом  и выпущен для общественности в 1991 году. В настоящее время он очень популярен и в основном используется в веб-разработке наряду с широко распространенными веб-фреймворками, такими как  djangoflaskbottlepy  и  pyramid . Название языка происходит от  Летающего цирка Монти Пайтона,  которым Гвидо был большим поклонником.

Какую версию мне использовать, 2.x или 3.x?

Официально поддерживаемая версия Python 2.7.x будет поддерживаться до 2020 года. Основная команда разработчиков языка подтвердила, что не будет версии 2.8 языка. Они будут отправлять только обновления безопасности и исправления ошибок для ветки 2.x. Ветвь 3.x была выпущена в 2000 году, у нее были проблемы в начале, но сейчас это очень хорошо. Переход на новую версию труден, так как большинство дистрибутивов Linux все еще поставляются с версией 2.x. Основной причиной этого является обратная совместимость; Есть много приложений, написанных с использованием ветки 2.x, и люди не хотят ломать существующие приложения. Ветка 3.x может быть легко установлена ​​помимо 2.x и может использоваться без каких-либо проблем.

Для более подробного объяснения различий, плюсов и минусов веток Python 2.x и 3.x, пожалуйста, прочитайте эти 2 статьи:

Занятия на Python

Как упоминалось выше, классы являются определениями типов объектов. Объявление класса в Python выполняется с помощью   ключевого слова class . В Python существует соглашение о кодировании, обычно  файл .py содержит только одно определение класса. Могут быть исключения, но это хорошая практика для подражания. Вот пример класса Gadget, о котором я говорил ранее:

class Gadget:


    weight = 100


    operating_system = None


    battery_capacity = 2000


    screen_size = 1


 


my_iphone = Gadget()

Класс  Gadget  имеет 4 атрибута ( весbattery_capacityoperating_system  и screen_size ). Мы можем создавать новые экземпляры класса, используя имя класса и круглые скобки — Gadget (). Если взглянуть на значения класса по умолчанию, они не будут правильными, если принять во внимание технические параметры iPhone. Нам понадобится метод или функция, которые позволят нам определить, каковы значения для данного экземпляра класса. Методы, которые помогают в создании нового экземпляра класса, называются конструкторами. Ниже вы можете увидеть реализацию конструктора ( __init__ ) в Python.  __init__ Метод вызывается сразу после создания нового экземпляра. Первый параметр конструктора называется  self . Это еще одно соглашение по коду. Первый параметр представляет объект, который является новым созданным новым, создавая новый экземпляр Как видите, мы устанавливаем атрибуты self внутри конструктора.

class Gadget:


    weight = 100


    operating_system = None


    battery_capacity = 2000


    screen_size = 1


 


    def __init__(self, weight, operating_system, battery_capacity, screen_size):


        self.weight = weight


        self.operating_system = operating_system


        self.battery_capacity = battery_capacity


        self.screen_size = screen_size


 


my_iphone = Gadget(weight = 128, operating_system="iOS", battery_capacity=2800, screen_size=4)

Если мы хотим увидеть, какие значения имеет наш новый объект, мы можем напечатать значения:

my_iphone = Gadget(weight = 128, operating_system="iOS", battery_capacity=2800, screen_size=4)


 


print(my_iphone.weight)


print(my_iphone.operating_system)


print(my_iphone.battery_capacity)


print(my_iphone.screen_size)

В этом подходе есть одна проблема: мы  нарушаем  правило инкапсуляции . У нас есть прямой доступ к внутреннему состоянию   объекта my_iphone , мы можем просто присвоить новые значения  атрибутам s creen_size  или  operating_system  . Текущая реализация модели позволяет это. Мы должны изменить их, используя свойства и скрывая текущих членов класса от публичного доступа.

class Gadget:


    """A class used for modelling Gadgets in a web shop."""


    __weight = 100


    __operating_system = None


    __battery_capacity = 2000


    __screen_size = 1


    def __init__(self, weight, operating_system, battery_capacity, screen_size):


        self.__weight = weight


        self.__operating_system = operating_system


        self.__battery_capacity = battery_capacity


        self.__screen_size = screen_size


 


    def get_weight(self):


        return self.__weight


 


    def set_weight(self, weight):


        self.__weight = weight


 


    weight = property(get_weight, set_weight)


 


    @property


    def operating_system(self):


        return self.__operating_system


 


    @operating_system.setter


    def operating_system(selg, new_os):


        self.__operating_system = new_os

Мы можем скрыть атрибуты (сделать их приватными), если объявим их с помощью  __
синтаксис ( для более подробной информации об этих соглашениях, пожалуйста, прочитайте [a href = «https://www.python.org/dev/peps/pep-0008/» target = «_ blank» style = «font-family: inherit; размер шрифта: 14px; стиль шрифта: унаследуют; начертание шрифта: унаследуют; цвет: RGB (87, 173, 104); «] PEP 8 Style Руководство по Python ) , и мы можем создать  сеттер и геттер  методы для доступа к частному атрибутов. Использование   методов getter и setter прекрасно, но обеспечивает Java-подобный подход к кодированию, где переменные класса могут быть установлены с помощью  методов get и set . Более дружественный подход для разработчиков — использование свойств. Я создал 2 свойства (для  weight  и operating_system ), каждое из которых реализовано по-своему.

При реализации свойства для  веса я использовал метод  weight = property (get_weight, set_weight)  для создания   свойства weight . Этот синтаксис может быть легко применен к классам Python, где Java-подобный метод get / set был реализован в первую очередь и с помощью метода  свойства (get…, set…)  мы можем расширить класс с помощью свойств.

При реализации свойства для  operating_system  я использовал другой подход, основанный на так называемой аннотации / декораторе. Здесь сначала я определил метод get, но я опустил ключевое слово get ( обратите внимание, что метод operating_system, украшенный @property, имеет только один параметр, self ); после этого я создал метод установки, который имеет то же имя метода ( operating_system ), но имеет 2 параметра, значение self и новое значение, которое необходимо установить (называемое  new_os ).

>>> from Gadget import Gadget


>>> my_iphone = Gadget(240,'iOS',1980,4)


>>> my_iphone.weight


240


>>> my_iphone.weight = 255


>>> my_iphone.weight


255


>>> 


>>> 


>>> my_iphone.operating_system


'iOS'


>>> my_iphone.operating_system = 'iOS 8.1'


>>> my_iphone.operating_system


'iOS 8.1'


>>> 

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

ООП в Python (2) появится в ближайшее время.