Python — это интерпретируемый язык программирования высокого уровня. Созданный Гвидо ван Россумом (Python был назван в честь британского комедийного шоу Монти Пайтон), философия дизайна Python делает упор на читабельность кода благодаря заметному использованию значительных пробелов. Его языковые конструкции и объектно-ориентированный подход призваны помочь программистам писать четкий, логичный код для небольших и крупных проектов.

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

Объектно-ориентированное программирование (ООП) — это способ программирования, который позволяет программистам думать так, как будто они работают с объектами, которые могут содержать данные, в в виде атрибутов и кода в виде методов. Все содержится в классе.

  • Класс — Категория объектов. Класс определяет все общие свойства различных объектов, которые ему принадлежат.
  • Объект — автономный объект, состоящий как из данных, так и из процедур для управления данными.
  • Метод – раздел программы, выполняющий определенную задачу.
  • Атрибуты — данные, инкапсулированные в классе или объекте.

Кроме того, OPP основан на следующих принципах:

  • Инкапсуляция. Реализация и состояние каждого объекта скрыты внутри определенной границы или класса.
  • Абстракция.Объекты раскрывают только внутренние механизмы, которые имеют отношение к использованию других объектов.
  • Наследование. Можно назначать отношения и подклассы между объектами, поддерживая уникальную иерархию.
  • Полиморфизм. Объекты могут принимать более одной формы в зависимости от контекста.

Это всего лишь атрибут!

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

  • Частный —используется и изменяется внутри класса. использует «__»
  • Защищено. Используется вне класса при определенных условиях. использует «_».
  • Общедоступный —используется и изменяется внутри и вне класса.

Атрибут класса?

Атрибут класса – это атрибут, общий для всех экземпляров класса. Давайте взглянем.

class Tim:    
    class_attribute = "There are some who call me... Tim"
Monty = Tim()
print(Tim.class_attribute)
print(Monty.class_attribute)

При выполнении мы получим следующий вывод:

There are some who call me... Tim
Are you suggesting that coconuts migrate?

Оба печатают одну и ту же цитату, это потому, что один является экземпляром Тима, а другой — сам класс, Тим, оба имеют один и тот же class_attribute.

Атрибут экземпляра?

Атрибут экземпляра принадлежит одному экземпляру класса и доступен только ему. Давайте взглянем.

class Tim:    
    class_attribute = "There are some who call me... Tim"
Monty = Tim()
Monty.class_attribute = "Are you suggesting that coconuts migrate?"
print(Tim.class_attribute)
print(Monty.class_attribute)

При выполнении мы получим следующий вывод:

There are some who call me... Tim
Are you suggesting that coconuts migrate?

Мы только что изменили атрибут класса class_attribute для Monty, так что его class_attribute является атрибутом экземпляра, доступным только для Monty.

Я создаю их в вашем общем направлении!

Мы создали атрибуты класса, объявив и присвоив им значение внутри класса, а также мы создали атрибуты экземпляра, объявив и присвоив им значение значение для них вне класса, тем не менее, мы не говорили о питоническом способе создания атрибутов…
Метод __init__ это метод, автоматически вызываемый после экземпляр класса, который был создан.

class Villain:
def __init__(self, name=''):
    self.name = name

Ключевое слово self относится к фактическому экземпляру класса. Теперь мы можем создать новый экземпляр Villain:

First_Villain = Villain("DOOM")

Будет вызван метод __init__, а имя экземпляра будет «DOOM».

Мы использовали общедоступные атрибуты для каждого примера, а как насчет частных? Мы также можем определить методы getter и setter, они будут извлекать значение и устанавливать значение атрибута экземпляра private соответственно. Метод __init__ вызовет метод установки, чтобы изменить значение атрибута.

class Villain:
   
    def __init__(self, name=''):
        self.name = name
    
    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self, value):
        self.__name = value

Строки с @ называются декораторами, они помогают классу искать, где получить и установить новые значения для атрибут. Затем мы используем слово self для обозначения фактического экземпляра, наконец, мы видим, что и свойство, и метод setter используют тот же def, но с другими аргументами. Это потому, что когда мы создаем новый экземпляр Villain, мы можем сделать следующее:

First_Villain = Villain("DOOM")
print(First_Villain.name)
First_villain.name = "METAL FINGER"
print(First_Villain.name)

При выполнении мы получим следующий вывод:

DOOM
METAL FINGER

В первой строке будет вызываться метод __init__, который, в свою очередь, вызывает сеттер, который устанавливает атрибут экземпляра в «DOOM», затем принимает новый аргумент для имени, еще раз устанавливает атрибут экземпляра «METAL FINGER».

А сейчас нечто соверешнно другое…

Вот основные различия между атрибутами класса и экземпляра:

  • Атрибуты класса —доступны для любого экземпляра класса.
  • Атрибут класса. Доступен через экземпляр или имя класса.
  • Атрибуты экземпляра —доступны только для этого конкретного экземпляра класса.
  • Атрибут экземпляра —доступен через экземпляр, которому он принадлежит.

Да, ну, знаешь, это как бы твое мнение, чувак...

Не все так ярко и красочно, у всего есть свои плюсы и минусы, атрибуты класса и экземпляра не исключение!

Атрибуты класса

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

( — ) Не может быть двух экземпляров с разными значениями.

Атрибуты экземпляра

(+)Их легко отслеживать и изменять, пока они находятся в конкретном объекте.

( — )Сложно и почти невозможно отслеживать значения между экземплярами.

Он прав, ты это знаешь ;)

Словарь __dict__ используется для хранения их атрибутов и соответствующих им значений. Именно так:

class Villain:
    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self, value):
        self.__name = value
    def __init__(self, name):
        self.name = name
First_Villain = Villain("DOOM")
Second_Villain = Villain("METAL FINGER")
print(First_Villain.__dict__)
print(Second_Villain.__dict__)

При выполнении мы получим следующий вывод:

{'_Villain__name': 'DOOM'}
{'_Villain__name': 'METAL FINGER'}

Конец фильма

ООП является естественным, универсальным и мощным, зная, как все работает, от небольшого атрибута до класса, все только начинает обретать форму, когда мы отражаем нашу работу в реальной жизни, как работают объекты и их функциональные возможности. В следующий раз, когда вы или ваша команда возьметесь за проект, рассмотрите возможность использования парадигмы ООП, удачного кодирования ;)!