Перейти к содержимому

Что такое класс в питоне программирование

  • автор:

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

Python имеет множество встроенных типов, например, int, str и так далее, которые мы можем использовать в программе. Но также Python позволяет определять собственные типы с помощью классов . Класс представляет некоторую сущность. Конкретным воплощением класса является объект.

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

Класс определяется с помощью ключевого слова class :

class название_класса: атрибуты_класса методы_класса

Внутри класса определяются его атрибуты, которые хранят различные характеристики класса, и методы — функции класса.

Создадим простейший класс:

class Person: pass

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

После создания класса можно определить объекты этого класса. Например:

class Person: pass tom = Person() # определение объекта tom bob = Person() # определение объекта bob

После определения класса Person создаются два объекта класса Person — tom и bob. Для создания объекта применяется специальная функция — конструктор , которая называется по имени класса и которая возвращает объект класса. То есть в данном случае вызов Person() представляет вызов конструктора. Каждый класс по умолчанию имеет конструктор без параметров:

tom = Person() # Person() - вызов конструктора, который возвращает объект класса Person

Методы классов

Методы класса фактически представляют функции, которые определенны внутри класса и которые определяют его поведение. Например, определим класс Person с одним методом:

class Person: # определение класса Person def say_hello(self): print("Hello") tom = Person() tom.say_hello() # Hello

Здесь определен метод say_hello() , который условно выполняет приветствие — выводит строку на консоль. При определении методов любого класса следует учитывать, что все они должны принимать в качестве первого параметра ссылку на текущий объект, который согласно условностям называется self . Через эту ссылку внутри класса мы можем обратиться к функциональности текущего объекта. Но при самом вызове метода этот параметр не учитывается.

Используя имя объекта, мы можем обратиться к его методам. Для обращения к методам применяется нотация точки — после имени объекта ставится точка и после нее идет вызов метода:

объект.метод([параметры метода])

Например, обращение к методу say_hello() для вывода приветствия на консоль:

tom.say_hello() # Hello

В итоге данная программа выведет на консоль строку «Hello».

Если метод должен принимать другие параметры, то они определяются после параметра self , и при вызове подобного метода для них необходимо передать значения:

class Person: # определение класса Person def say(self, message): # метод print(message) tom = Person() tom.say("Hello METANIT.COM") # Hello METANIT.COM

Здесь определен метод say() . Он принимает два параметра: self и message. И для второго параметра — message при вызове метода необходимо передать значение.

self

Через ключевое слово self можно обращаться внутри класса к функциональности текущего объекта:

self.атрибут # обращение к атрибуту self.метод # обращение к методу

Например, определим два метода в классе Person:

class Person: def say(self, message): print(message) def say_hello(self): self.say("Hello work") # обращаемся к выше определенному методу say tom = Person() tom.say_hello() # Hello work

Здесь в одном методе — say_hello() вызывается другой метод — say() :

self.say("Hello work")

Поскольку метод say() принимает кроме self еще параметры (параметр message), то при вызове метода для этого параметра передается значение.

Причем при вызове метода объекта нам обязательно необходимо использовать слово self , если мы его не используем:

def say_hello(self): say("Hello work") # ! Ошибка

То мы столкнемся с ошибкой

Конструкторы

Для создания объекта класса используется конструктор. Так, выше когда мы создавали объекты класса Person, мы использовали конструктор по умолчанию, который не принимает параметров и который неявно имеют все классы:

tom = Person()

Однако мы можем явным образом определить в классах конструктор с помощью специального метода, который называется __init__() (по два прочерка с каждой стороны). К примеру, изменим класс Person, добавив в него конструктор:

class Person: # конструктор def __init__(self): print("Создание объекта Person") def say_hello(self): print("Hello") tom = Person() # Создание объекта Person tom.say_hello() # Hello

Итак, здесь в коде класса Person определен конструктор и метод say_hello() . В качестве первого параметра конструктор, как и методы, также принимает ссылку на текущий объект — self. Обычно конструкторы применяются для определения действий, которые должны производиться при создании объекта.

Теперь при создании объекта:

tom = Person()

будет производится вызов конструктора __init__() из класса Person, который выведет на консоль строку «Создание объекта Person».

Атрибуты объекта

Атрибуты хранят состояние объекта. Для определения и установки атрибутов внутри класса можно применять слово self . Например, определим следующий класс Person:

class Person: def __init__(self, name): self.name = name # имя человека self.age = 1 # возраст человека tom = Person("Tom") # обращение к атрибутам # получение значений print(tom.name) # Tom print(tom.age) # 1 # изменение значения tom.age = 37 print(tom.age) # 37

Теперь конструктор класса Person принимает еще один параметр — name. Через этот параметр в конструктор будет передаваться имя создаваемого человека.

Внутри конструктора устанавливаются два атрибута — name и age (условно имя и возраст человека):

def __init__(self, name): self.name = name self.age = 1

Атрибуту self.name присваивается значение переменной name. Атрибут age получает значение 1.

Если мы определили в классе конструктор __init__, мы уже не сможем вызвать конструктор по умолчанию. Теперь нам надо вызывать наш явным образом опреледеленный конструктор __init__, в который необходимо передать значение для параметра name:

tom = Person("Tom")

Далее по имени объекта мы можем обращаться к атрибутам объекта — получать и изменять их значения:

print(tom.name) # получение значения атрибута name tom.age = 37 # изменение значения атрибута age

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

class Person: def __init__(self, name): self.name = name # имя человека self.age = 1 # возраст человека tom = Person("Tom") tom.company = "Microsoft" print(tom.company) # Microsoft

Здесь динамически устанавливается атрибут company, который хранит место работы человека. И после установки мы также можем получить его значение. В то же время подобное определение чревато ошибками. Например, если мы попытаемся обратиться к атрибуту до его определения, то программа сгенерирует ошибку:

tom = Person("Tom") print(tom.company) # ! Ошибка - AttributeError: Person object has no attribute company

Для обращения к атрибутам объекта внутри класса в его методах также применяется слово self:

class Person: def __init__(self, name): self.name = name # имя человека self.age = 1 # возраст человека def display_info(self): print(f"Name: Age: ") tom = Person("Tom") tom.display_info() # Name: Tom Age: 1

Здесь определяется метод display_info(), который выводит информацию на консоль. И для обращения в методе к атрибутам объекта применяется слово self: self.name и self.age

Создание объектов

Выше создавался один объект. Но подобным образом можно создавать и другие объекты класса:

class Person: def __init__(self, name): self.name = name # имя человека self.age = 1 # возраст человека def display_info(self): print(f"Name: Age: ") tom = Person("Tom") tom.age = 37 tom.display_info() # Name: Tom Age: 37 bob = Person("Bob") bob.age = 41 bob.display_info() # Name: Bob Age: 41

Здесь создаются два объекта класса Person: tom и bob. Они соответствуют определению класса Person, имеют одинаковый набор атрибутов и методов, однако их состояние будет отличаться.

При выполнении программы Python динамически будет определять self — он представляет объект, у которого вызывается метод. Например, в строке:

tom.display_info() # Name: Tom Age: 37

Это будет объект tom

bob.display_info()

Это будет объект bob

В итоге мы получим следующий консольный вывод:

Name: Tom Age: 37 Name: Bob Age: 41

Классы¶

Класс — шаблон, с помощью которого удобно описывать однотипные объекты. В классе соержатся свойства, правила создания и поведение объекта.

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

Пример класса — автомобили, его атрибутами будут: цвет, марка автомобиля, регистрационный номер.

Методами могут быть: ехать прямо, повернуть, остановиться.

Объектом класса “Автомобили” может быть конкретный автомобиль, например, Renault Logan белого цвета с номером М123РТ.

Для чего нужны классы?

Классы помогают кратко и понятно описывать объекты и их поведение независимо от основного кода программы.

Затем в основном коде можно просто создавать объекты на основе классов и работать с ними, уже не описывая их свойств и поведения.

Такой подход делает код более читаемым и понятным, а также помогает избежать многих ошибок и багов.

Синтаксис и правила создания классов¶

Для создания класса используется конструкция class ClassName . Согласно договорённостям имя класса всегда пишется с большой буквы.

Каждый класс должен содержать метод __init__ — с помощью этого метода создаётся объект класса. В этом методе инициализируются атрибуты класса:

class Person: # Объявления класса def __init__(self, name, age): # Метод инициализации self.age = age # Установка значений атрибутов self.name = name 

Также в классах могут быть использованы встроенные методы, их называют магическими. Магические методы — зарезервированные методы, отвечающие за поведение объекта.

Объектно-ориентированное программирование. Классы и объекты

Python 3 логотип

Сегодня мы поговорим об объектно-ориентированном программировании и о его применении в python.

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

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

Python соответствует принципам объектно-ориентированного программирования. В python всё является объектами — и строки, и списки, и словари, и всё остальное.

Но возможности ООП в python этим не ограничены. Программист может написать свой тип данных (класс), определить в нём свои методы.

Это не является обязательным — мы можем пользоваться только встроенными объектами. Однако ООП полезно при долгосрочной разработке программы несколькими людьми, так как упрощает понимание кода.

Приступим теперь собственно к написанию своих классов на python. Попробуем определить собственный класс:

  Теперь мы можем создать несколько экземпляров этого класса:
       File 

Классу возможно задать собственные методы:

И напоследок еще один пример:

Для вставки кода на Python в комментарий заключайте его в теги

  • Модуль csv - чтение и запись CSV файлов
  • Создаём сайт на Django, используя хорошие практики. Часть 1: создаём проект
  • Онлайн-обучение Python: сравнение популярных программ
  • Книги о Python
  • GUI (графический интерфейс пользователя)
  • Курсы Python
  • Модули
  • Новости мира Python
  • NumPy
  • Обработка данных
  • Основы программирования
  • Примеры программ
  • Типы данных в Python
  • Видео
  • Python для Web
  • Работа для Python-программистов
  • Сделай свой вклад в развитие сайта!
  • Самоучитель Python
  • Карта сайта
  • Отзывы на книги по Python
  • Реклама на сайте

Классы в Python

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

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

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

Создание и использование классов

При помощи классов можно моделировать почти все. Давайте начнем с написания простого класса Dog , который представит объект или шаблон собаки. Используя этот класс, шаблон можно организовать создание других объектов "собаки" на основе такого шаблона. Прежде чем создать класс, нужно понять, какими параметрами или свойствами обладают собаки? Так, у них всех есть имя и возраст. Мы также знаем, что большинство собак могут исполнять команды "сидеть" или "переворачиваться". Эти части данных (имя и возраст) и эти два поведения ("сидеть" и "переворачиваться") войдут в наш класс Dog , потому что они являются общими для большинства собак. После написания нашего класса мы будем использовать его для создания отдельных экземпляров, каждый из которых представляет одну конкретную собаку.

Пример создания простого класса

Каждый экземпляр, созданный из класса Dog , будет хранить имя и возраст, и мы дадим каждой собаке выполнять действия sit( ) и roll_over() :

class Dog: """A simple attempt to model a dog.""" def __init__(self, name, age): """Initialise name and age attributes.""" self.name = name.title() self.age = age def sit(self): """Simulate a dog sitting in response to a command.""" print(self.name + " is now sitting.") def roll_over(self): """Simulate rolling over in response to a command.""" print(self.name + " rolled over!") 

Код сначала может казаться непонятным, но мы сейчас всё поясним. Такая стандартная структура будет использоваться достаточно часто, поэтому нужно привыкнуть к ней. И так, в самом начале мы определяем класс с именем Dog . Так принято в Python, что все классы начинаются с заглавной буквы. Затем в тройных кавычках можно комментировать, что означает последующий код, так как это информация будет включена в документацию к программе для тех, кто может работать с кодом в последующем.

Метод __init__()

Функция, которая является частью класса, называется методом. Все, что вы узнали о функциях, относится и к методам; единственное практическое отличие на данный момент - это то, как мы будем вызывать методы. __init __() в коде - это специальный метод, который Python запускает автоматически всякий раз, когда мы создаем новый экземпляр на основе класса Dog . Этот метод выделяется двойными подчёркиваниями.

Мы определяем метод __init __( ) для трех параметров: "self", "name" и "age". Параметр "self" является обязательным в определении метода и должен предшествовать другим параметрам. Он должен быть включен в определение, потому что когда Python позже вызывает этот метод __init __() (для создания экземпляра Dog ), вызов метода автоматически передаст аргумент "self". Каждый вызов метода, связанный с классом, автоматически передает себя, что является ссылкой на сам экземпляр; он дает экземпляру доступ к атрибутам и методам в классе. Когда мы создаем экземпляр Dog , Python вызывает метод __init __() из класса Dog . Мы передадим классу Dog() имя и возраст в качестве аргументов; "self" передается автоматически, поэтому нам не нужно его передавать. Всякий раз, когда мы хотим создать экземпляр из класса Dog , мы предоставим значения для двух параметров - имени и возраста.

Две переменные, написанные в коде, имеют префикс "self". Любая переменная с префиксом "self" доступна каждому методу в классе, и мы также сможем получить доступ к этим переменным через любой экземпляр, созданный из класса. self.name = name.title() принимает значение, сохраненное в имени параметра, и сохраняет его в имени переменной, которая затем присоединяется к создаваемому экземпляру. При этом мы используем функцию title() , которая выводит все значения в переменной с заглавной буквы. Тот же процесс происходит с self.age = age . Переменные, доступные через такие экземпляры, называются атрибутами.

Класс Dog имеет два других метода в нашем примере: sit() и roll_over() . Так как эти методы не нуждаются в дополнительной информации, такие как имя или возраст, мы просто определяем их как один параметр - self. Экземпляры, которые мы создадим позже, будут иметь доступ к этим методам. Другими словами, мы присваиваем объекту действия для собаки: садиться и переворачиваться. В данном примере методы sit() и roll_over() просто выводят сообщение о том, что собака села или переворачивается. Имейте в виду, что концепция может быть расширена до реалистичных ситуаций: если бы этот класс был частью реальной компьютерной игры, эти методы содержали бы код, заставляющий анимированную собаку садиться и переворачиваться.

Создание экземпляра из класса

Думайте о классе как о наборе инструкций о том, как создать экземпляр. Класс Dog - это набор инструкций, который сообщает Python, как создавать отдельные экземпляры, представляющие конкретных собак Давайте сделаем пример, представляющий конкретную собаку. После кода определяющий класс Dog вносим следующий код:

my_dog = Dog('willie', 6) print("My dog's name is " + my_dog.name + ".") print("My dog is " + str(my_dog.age) + " years old.") 

Класс Dog , который мы здесь используем, - это тот, который мы только что написали в предыдущем примере. Сначала мы сообщаем Python создать собаку с именем "willie" и возрастом 6 лет. Когда Python читает эту строку, он вызывает метод __init __() в Dog с аргументами "willie" и "6". Метод __init __() создает экземпляр, представляющий эту конкретную собаку и устанавливающий атрибуты имени и возраста с использованием предоставленных нами значений. Метод __init __ () не имеет явного оператора return, но Python автоматически возвращает экземпляр, представляющий эту собаку. Мы храним этот экземпляр в переменной my_dog . В нашем примере название заглавное Dog , относится к классу, а строчное имя, например, my_dog , относится к одному экземпляру, созданному из класса.

Доступ к атрибутам

Для доступа к атрибутам экземпляра используется точечная запись. Так в коде мы получаем доступ к значению имени атрибута my_dog , написав:

my_dog.name 

Точечная нотация часто используется в Python. Этот синтаксис демонстрирует, как Python находит значение атрибута. Здесь Python использует экземпляр my_dog и затем находит атрибут "name", связанное с my_dog . Это тот же атрибут, который называется self.name в классе Dog . Затем в коде мы используем такой же подход для работы с атрибутом age (возраст). Во втором выводе значение атрибута my_dog.age преобразует значение в строку. Вывод представляет собой сводку того, что мы знаем о my_dog :

My dog's name is Willie. My dog is 6 years old.
Вызов методов

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

my_dog = Dog('willie', 6) my_dog.sit() my_dog.roll_over() 

Чтобы вызвать метод, нужно задать названия экземпляра (в данном случае my_dog и метод, который вы хотите вызвать, через точку. Когда Python читает my_dog.sit() , он ищет метод sit() в классе Dog и запускает этот код. Python интерпретирует строку my_dog.roll_over() таким же образом. Теперь наша виртуальная собака делает то, что мы сообщаем ей:

Willie is now sitting. Willie rolled over!

Такой синтаксис довольно полезен. Когда атрибутам и методам присвоены соответствующие описательные имена, такие как name , age , sit() и roll_over() , мы можем легко определить, что должен делать блок кода.

Создание нескольких экземпляров

Вы можете создать столько экземпляров из класса, сколько нужно. Давайте создадим вторую собаку с именем your_dog :

my_dog = Dog('willie', 6) your_dog = Dog('lucy', 3) print("My dog's name is " + my_dog.name.title() + ".") print("My dog is " + str(my_dog.age) + " years old.") print("\nYour dog's name is " + your_dog.name.title() + ".") print("Your dog is " + str(your_dog.age) + " years old.") your_dog.sit() my_dog.sit() 

В этом примере мы создаем собаку по имени "Willie" и собаку по имени "Lucy". Каждая собака - это отдельный экземпляр со своим набором атрибутов, способный выполнять один и тот же набор действий:

My dog's name is Willie. My dog is 6 years old. Willie is now sitting. Your dog's name is Lucy. Your dog is 3 years old. Lucy is now sitting.

Даже если бы мы использовали то же имя и возраст для второй собаки, Python все равно создал бы отдельный экземпляр из класса Dog . Можно создать столько экземпляров из одного класса, сколько нужно, при условии, что даете каждому экземпляру уникальное имя переменной или оно занимает уникальное место в списке или словаре.

Работа с классами и экземплярами

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

Класс автомобиля

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

class Car: def __init__(self, make, model, year): """Initialize attributes to describe a car.""" self.make = make self.model = model self.year = year def get_descriptive_name(self): """Return a neatly formatted descriptive name.""" long_name = str(self.year) + ' ' + self.make + ' ' + self.model return long_name.title() my_new_car = Car('audi', 'a4', 2016) print(my_new_car.get_descriptive_name()) 

В начале класса "Car" мы сначала определяем метод __init __() с параметром self , как мы делали это раньше с нашим классом c. Затем этому классу задаём три других параметра: марка, модель и год автомобиля. Метод __init __( ) принимает эти параметры и сохраняет их в атрибутах, которые будут связаны с экземплярами, созданными из этого класса. Когда мы создаем новый экземпляр "Car", нам нужно указать марку, модель и год для нашего автомобиля.

Затем мы определяем метод get_descriptive_name( ), который помещает год, марку и модель автомобиля в одну строку, описывающий автомобиль. Это избавит нас от необходимости печатать значение каждого атрибута отдельно. Для работы со значениями атрибутов в этом методе мы используем self.make , self.model и self.yea r. Потом создаём экземпляр из класса Car и сохраняем его в переменной my_new_car . Затем мы вызываем get_descriptive_name() , чтобы показать, какая у нас машина:

2016 Audi A4

Чтобы сделать класс более интересным, давайте добавим атрибут, который меняется со временем. Мы добавим атрибут, который хранит общий пробег автомобиля.

Установка значения по умолчанию для атрибута

Каждому атрибуту в классе необходимо задать начальное значение, даже если это значение равно 0 или пустой строке. В некоторых случаях, например при установке значения по умолчанию, имеет смысл указать начальное значение в теле метода __init __() ; если вы делаете это для атрибута, вам не нужно включать параметр для этого атрибута.

Давайте добавим атрибут с именем odometer_reading , который всегда имеет значение "0". Мы также добавим метод read_odometer() , который поможет считывать значения счётчика каждого автомобиля:

class Car(): def __init__(self, make, model, year): """Initialize attributes to describe a car.""" self.make = make self.model = model self.year = year self.odometer_reading = 0 def get_descriptive_name(self): --snip-- def read_odometer(self): """Print a statement showing the car's mileage.""" print("This car has " + str(self.odometer_reading) + " miles on it.") my_new_car = Car('audi', 'a4', 2016) print(my_new_car.get_descriptive_name()) my_new_car.read_odometer() 

На этот раз, когда Python вызывает метод __init __( ) для создания нового экземпляра, он сохраняет значения make , model и year в виде таких атрибутов, как это было в предыдущем примере. Затем Python создает новый атрибут с именем odometer_reading и устанавливает его начальное значение равным "0". У нас также есть новый метод read_odometer() , который облегчает считывание пробега автомобиля. Так пробег нашего виртуального автомобиля равняется нулю:

2016 Audi A4 This car has 0 miles on it.

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

Изменение значений атрибутов

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

Прямое изменение значения атрибута

Самый простой способ изменить значение атрибута - получить доступ к атрибуту напрямую через экземпляр. Здесь мы устанавливаем показания счётчика на 23:

class Car(): --snip-- my_new_car = Car('audi', 'a4', 2016) print(my_new_car.get_descriptive_name()) my_new_car.odometer_reading = 23 my_new_car.read_odometer() 

Сначала используем используем запись через точку, чтобы получить доступ к атрибуту odometer_reading нашего виртуального автомобиля и установить его значение напрямую. Эта строка сообщает Python взять экземпляр my_new_car , найти связанный с ним атрибут odometer_reading и установить значение этого атрибута равным "23":

2016 Audi A4 This car has 23 miles on it.

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

Изменение значения атрибута с помощью метода

Иногда нужно увеличить значение атрибута на определенную величину, а не устанавливать совершенно новое значение. Предположим, мы покупаем подержанный автомобиль c пробегаем 100 километров между моментом покупки и моментом регистрации. Есть метод, который позволяет нам передать это значение и добавить его к показаниям счётчика:

class Car(): --snip-- def update_odometer(self, mileage): """Set the odometer reading to the given value.""" self.odometer_reading = mileage my_new_car = Car('audi', 'a4', 2016) print(my_new_car.get_descriptive_name()) my_new_car.update_odometer(23) my_new_car.read_odometer() 

Единственная модификация к кдассу Car - это добавление метода update_odometer() . Этот метод принимает значение пробега и сохраняет его в self.odometer_reading . Затем вызываем update_odometer() и передаем ему значение "23" в качестве аргумента (соответствует параметру пробега в определении метода). Он устанавливает показание счётчика на 23, и получаем результат:

2016 Audi A4 This car has 23 miles on it.

Можно расширить метод update_odometer() , чтобы не выполнять дополнительную процесс каждый раз, когда изменяется показание счётчика. Давайте добавим немного логики, чтобы убедиться, чтобы никто не смог откатить показания счётчика:

class Car(): --snip-- def update_odometer(self, mileage): """ Set the odometer reading to the given value. Reject the change if it attempts to roll the odometer back. """ if mileage >= self.odometer_reading: self.odometer_reading = mileage else: print("You can't roll back an odometer!") 

Теперь метод update_odometer() проверяет, имеет ли новое значение новое значение, прежде чем изменять этот атрибут. Если новое значение больше или равно существующему значению "self.odometer_reading", то можно обновить показания счётчика до нового показания. Если новое значение меньше существующего, то получите предупреждение о том, что нельзя откатить показания счётчика.

Увеличение значения атрибута с помощью метода

Иногда необходимо увеличить значение атрибута на определенную величину, а не устанавливать новое значение для него. Скажем, мы покупаем подержанный автомобиль и проезжаем 100 километров. Вот метод, который позволяет нам передать это значение и добавляет его к показанию счётчика:

class Car: -- snip -- def update_odometer(self, mileage): -- snip -- def increment_odometer(self, miles): """Add the given amount to the odometer reading.""" self.odometer_reading += miles my_new_car = Car('audi', 'a4', 2016) my_used_car = Car('subaru', 'outback', 2013) print(my_used_car.get_descriptive_name()) my_used_car.update_odometer(23500) my_used_car.read_odometer() my_used_car.increment_odometer(100) my_used_car.read_odometer() 

Новый метод increment_odometer() добавляет нужное значение в параметр self.odometer_reading . Далее мы создаем дополнительный автомобиль my_used_car . Затем устанавливаем параметр счётчика 23 500. Потом вызываем функцию обновления счётчика update_odometer() и передаём значение "100". добавить 100 миль. И соответственно получаем на выходе:

2013 Subaru Outback This car has 23500 miles on it. This car has 23600 miles on it.

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

Унаследование

При создании классов в Python не всегда нужно их делать заново, когда есть похожие параметры объекта, то можно использовать так называемое унаследование.

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

Метод __init __ () для дочернего класса

Первая задача при создании экземпляра из дочернего класса - присвоить значения всем атрибутам в родительском классе. Для этого методу __init __ () дочернего класса требуется помощь его родительского класса.

В качестве примера давайте смоделируем электромобиль. Электромобиль - это просто особый вид автомобиля, поэтому мы можем добавить наш новый класс ElectricCar на базе класса Car , который мы написали ранее. Тогда нам останется только написать код для атрибутов и поведения, характерных для электромобилей.

Давайте начнем с создания простой версии класса ElectricCar , который делает все, что делает класс Car :

class Car: def __init__(self, make, model, year): """Initialize attributes to describe a car.""" self.make = make self.model = model self.year = year self.odometer_reading = 0 # Preset parameter def get_descriptive_name(self): """Return a neatly formatted descriptive name.""" long_name = str(self.year) + ' ' + self.make + ' ' + self.model return long_name.title() def read_odometer(self): """Print a statement showing the car's mileage.""" print("This car has " + str(self.odometer_reading) + " miles on it.") def update_odometer(self, mileage): """Set the odometer reading to the given value. Reject the change if it attempts to roll the odometer back.""" if mileage >= self.odometer_reading: self.odometer_reading = mileage else: print("You can't roll back an odometer!") def increment_odometer(self, miles): """Add the given amount to the odometer reading.""" if self.odometer_reading - miles >= self.odometer_reading: print('You cannot use negative values') else: self.odometer_reading += miles class ElectricCar(Car): """Represent aspects of a car, specific to electric vehicles.""" def __init__(self, make, model, year): """Initialize attributes of the parent class.""" super().__init__(make, model, year) my_tesla = ElectricCar('tesla', 'model s', 2016) print(my_tesla.get_descriptive_name()) 

На 33-й строке мы начинаем с класса Car . Когда вы создаете дочерний класс, он должен быть частью родительского класса и необходимо его указывать после кода дочернего класса. На 35-й строке мы задаём дочерний класс ElectricCar . Имя родительского класса должно быть заключено в круглые скобки в определении дочернего класса. Метод __init __() принимает информацию, необходимую для создания экземпляра Car .

Функция super() на 37-й строке - это специальная функция, которая помогает Python устанавливать связи между родительским и дочерним классами. Эта строка указывает вызывать метод __init __() из родительского класса ElectricCar , который передает экземпляру ElectricCar все атрибуты его родительского класса. Название super происходит от соглашения о назывании родительского класса суперклассом, а дочернего класса - подклассом.

Далее мы проверяем, правильно ли срабатывает унаследование, создавая класс электромобиля с теме же данными, которые мы задавали при создании класса обычного автомобиля. Потом мы создаем экземпляр класса ElectricCar и сохраняем его в переменной my_tesla (39-я строка). Эта строка вызывает метод __init __() , заданный в ElectricCar, определенный в родительском классе Car . И как результат мы добавляем аргументы «Tesla», «Model S» и год выпуска автомобиля "2016".

Помимо __init __( ), пока не заданы атрибуты или методы, специально для электромобиля. На данный момент мы просто убеждаемся, что электромобиль имеет соответствующее поведение класса автомобиля:

2016 Tesla Model S

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

Определение атрибутов и методов для дочернего класса

Когда есть дочерний класс, который наследуется от родительского класса, можно добавить любые новые атрибуты и методы отличные от дочернего родительского класса.

Давайте добавим атрибут, который присущ электромобилям (например, аккумулятор), и метод вывода по этому атрибуту. Мы сохраним размер батареи и напишем метод, выводящий описание батареи:

class Car(): --snip-- class ElectricCar(Car): """Represent aspects of a car, specific to electric vehicles.""" def __init__(self, make, model, year): """ Initialize attributes of the parent class. Then initialize attributes specific to an electric car. """ super().__init__(make, model, year) self.battery_size = 70 def describe_battery(self): """Print a statement describing the battery size.""" print("This car has a " + str(self.battery_size) + "-kWh battery.") my_tesla = ElectricCar('tesla', 'model s', 2016) print(my_tesla.get_descriptive_name()) my_tesla.describe_battery() 

На 13 строчке мы добавляем новую переменную self.battery_size , содержащую значение заряда батареи. Этот атрибут будет связан со всеми экземплярами, созданными из класса "ElectricCar", но не будет связан ни с одним экземпляром класса Car . Мы также добавим метод description_battery() - строка 15, который выводит информацию о батарее. Запустив программу, мы получим следующий результат:

2016 Tesla Model S This car has a 70-kWh battery.

Нет предела тому, сколько и как можно редактировать класс ElectricCar , добавляя неограниченное количество атрибутов классу Car (не ограничиваясь только электромобилем). Таким образом используя данный класс у разработчика есть доступ ко всему функционалу данного класса.

Переопределение методов из родительского класса

Данный раздел находится в стадии доработки.

  • Автор статьи работает над завершением этой статьи.
  • Свои пожелания, комментарии и вопросы оставляйте на странице обсуждения.

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

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