- Переменные класса и экземпляра в Python 3
- Переменные класса
- Объектные переменные
- Работа с переменными класса и объекта
- Заключение
- Понимание переменных класса и экземпляра в Python 3
- Переменные класса и экземпляра
- Переменные класса
- Переменные экземпляра
- Резюме
- Чего ожидать от переменных класса
- Изменение переменной класса
- Изменение переменной экземпляра
- Переменные экземпляра переопределяют переменные класса (и методы)
- Использование изменяемых объектов в качестве переменных класса
- Заключение
Переменные класса и экземпляра в Python 3
В объектно-ориентированном программировании переменные можно использовать на уровне класса или объекта. Переменная – это символ, который заменяет какое-либо значение в программе.
Если какая-либо переменная будет иметь одно и то же значение во всех объектах программы, её можно определить на уровне класса. Если значение переменной будет изменяться в зависимости от объекта, такую переменную нужно определить на уровне экземпляра (объекта).
DRY (don’t repeat yourself, рус. не повторяйся) – это принцип программирования, который подразумевает снижение повторений кода в рамках программы.
Данное руководство научит пользоваться переменными класса и объектными переменными (или переменными экземпляра) в объектно-ориентированном программировании в Python.
Переменные класса
Переменные класса определяются на уровне класса и применяются ко всем объектам, созданным на его основе. Такая переменная, как правило, имеет одно и то же значение внутри всех объектов на основе этого класса (если только она не используется для инициализации переменной).
Переменная класса, определяемая вне метода, как правило, пишется под заголовком класса и перед методом конструктора и другими методами.
Переменная класса выглядит так:
class Shark:
animal_type = «fish»
Создайте тестовую программу shark.py. В этом файле можно создать экземпляр класса Shark (например, new_shark) и вывести переменную с помощью точечной нотации:
class Shark:
animal_type = «fish»
new_shark = Shark()
print(new_shark.animal_type)
Программа отобразила значение переменной.
Добавьте в класс больше переменных и отобразите их:
class Shark:
animal_type = «fish»
location = «ocean»
followers = 5
new_shark = Shark()
print(new_shark.animal_type)
print(new_shark.location)
print(new_shark.followers)
Как и другие виды переменных Python, переменные класса могут содержать любой тип данных. В данной программе переменные будут содержать строки и целые числа.
Снова запустите программу:
Объект new_shark имеет доступ ко всем переменным класса и может отобразить их на экране.
Объектные переменные
Объектные переменные имеют индивидуальное значение внутри того или иного объекта.
В отличие от переменных класса, объектные переменные определяются внутри метода.
К примеру, в классе Shark переменные name и age являются объектными.
class Shark:
def __init__(self, name, age):
self.name = name
self.age = age
Объектные переменные определяются при создании класса Shark, а затем передаются объекту в качестве параметров метода конструктора или другого метода.
class Shark:
def __init__(self, name, age):
self.name = name
self.age = age
new_shark = Shark(«Wally», 5)
Как и переменные класса, объектные переменные можно отобразить:
class Shark:
def __init__(self, name, age):
self.name = name
self.age = age
new_shark = Shark(«Wally», 5)
print(new_shark.name)
print(new_shark.age)
Полученный результат состоит из значений переменных, которые были инициализированы для объекта new_shark.
Создайте ещё один объект класса Shark (например, stevie):
class Shark:
def __init__(self, name, age):
self.name = name
self.age = age
new_shark = Shark(«Wally», 5)
print(new_shark.name)
print(new_shark.age)
stevie = Shark(«Stevie», 8)
print(stevie.name)
print(stevie.age)
Объект stevie, как и объект new_shark, передает индивидуальные параметры экземпляра класса Shark.
Объектные переменные имеют разные значения внутри каждого объекта.
Работа с переменными класса и объекта
Переменные класса и объектные переменные часто используются вместе. Давайте рассмотрим пример кода, в котором использованы оба вида переменных.
# Переменные класса
animal_type = «fish»
location = «ocean»
# Метод конструктора с объектными переменными name и age
def __init__(self, name, age):
self.name = name
self.age = age
# Метод с объектной переменной followers
def set_followers(self, followers):
print(«This user has » + str(followers) + » followers»)
def main():
# Первый объект определяет объектные переменные метода конструктора
wally = Shark(«Wally», 5)
# Отображение объектной переменной name
print(wally.name)
# Отображение переменной класса location
print(wally.location)
# Второй объект
stevie = Shark(«Stevie», 8)
# Отображение объектной переменной name
print(stevie.name)
# Использование метода set_followers и передача объектной переменной followers
stevie.set_followers(77)
# Отображение переменной класса animal_type
print(stevie.animal_type)
if __name__ == «__main__»:
main()
Вы получите такой результат:
Wally
ocean
Stevie
This user has 77 followers
fish
Заключение
В объектно-ориентированном программировании переменные на уровне класса называются переменными класса, а переменные на уровне объекта называются объектными переменными.
Переменные класса можно использовать для инициализации объектов с определенным значением, присвоенным переменным. Объектные переменные имеют индивидуальное значение внутри каждого объекта.
Это позволяет разрабатывать программы по принципу DRY и уменьшить повторение кода.
Понимание переменных класса и экземпляра в Python 3
При изучении объектно-ориентированного программирования на Python может возникнуть несколько сложностей, когда дело доходит до разграничения переменных класса и экземпляра. В этом руководстве я объясню разницу между переменными класса и экземпляра и приведу примеры, демонстрирующие различные варианты использования.
Переменные класса и экземпляра
Во-первых, быстрый обзор, если вы новичок в объектно-ориентированном программировании. Класс — это шаблон для создания объектов, а экземпляр — это сам объект. Классы часто представляют что-то в реальном мире, так что представьте, хотите ли вы создать класс, списка студентов. Вы можете создать класс с именем Student, который представляет собой шаблон, который определяет различные атрибуты студента. Таким образом, каждый студент является экземпляром класса Student.
При работе с данными любого типа некоторые атрибуты будут уникальными, а некоторые будут общими. Рассмотрим пример с учениками: у каждого учащегося в этом классе один и тот же номер и один учитель, но у каждого из них есть уникальное имя, возраст и любимый предмет.
Переменные класса
Переменные класса обычно являются переменными, которые являются общими для всех экземпляров. И они определены так:
class Student: teacher = 'Mrs. Jones' # переменная класса
Каждый экземпляр класса будет иметь одинаковое значение для этих переменных:
tom = Student() susan = Student() print(tom.teacher) >> "Mrs. Jones" print(susan.teacher) >> "Mrs. Jones"
Переменные экземпляра
Переменные экземпляра (также называемые атрибутами данных) уникальны для каждого экземпляра класса и определяются в методе класса, например:
class Student: teacher = 'Mrs. Jones' # переменная класса def __init__(self, name): self.name = name # переменная экземпляра
Посмотрите, как каждый экземпляр теперь содержит уникальное значение name:
tom = Student('Tom') susan = Student('Susan') print(tom.name) >> "Tom" print(susan.name) >> "Susan"
Резюме
Это был только базовый обзор переменных класса и экземпляра. Мы углубимся в следующие шаги, но наиболее важный вывод заключается в том, что переменные класса обычно используются для значений, которые являются общими для всех экземпляров класса, в то время как переменные экземпляра используются для значений, уникальных для каждого экземпляра.
Чего ожидать от переменных класса
Переменные класса являются общими для всех экземпляров класса. Напоминаем, что они определены так:
class Student: teacher = 'Mrs. Jones'
Иными словами, переменные класса ссылаются на одно и то же место в памяти. Смотрите следующее:
tom = Student() susan = Student() id(tom.teacher) == id(susan.teacher) >> True
Функция id возвращает адрес объекта в памяти для реализации CPython.
Таким образом, с помощью функции id мы можем подтвердить, что атрибут teacher ссылается на то же место в памяти.
Изменение переменной класса
Что произойдет, если мы изменим переменную класса даже после создания экземпляров?
tom = Student() tom.teacher >> Mrs. Jones Student.teacher = 'Mr. Smith' tom.teacher >> Mr. Smith
Как и следовало ожидать, поскольку переменная teacher ссылается на общее местоположение в памяти, она также обновляется в экземпляре.
Изменение переменной экземпляра
Это, вероятно, наиболее очевидное и ожидаемое поведение, поэтому не стесняйтесь пропустить этот шаг. Но я все же покажу несколько примеров для полноты.
Рассмотрим наш класс Student с переменными класса и экземпляра:
class Student: teacher = 'Mrs. Jones' def __init__(self, name): self.name = name
Мы видим, что каждый экземпляр класса имеет уникальный адрес памяти для имени:
tom = Student('Tom') susan = Student('Susan') id(tom.name) == id(susan.name) >> False
Как и следовало ожидать, обновление атрибута name в одном экземпляре не влияет на другой:
tom.name >> Tom susan.name >> Susan tom.name = 'Thomas' tom.name >> Thomas susan.name >> Susan
Переменные экземпляра переопределяют переменные класса (и методы)
Важно отметить, что переменные экземпляра (или атрибуты данных) переопределяют переменные класса.
tom = Student() susan = Student() id(tom.teacher) == id(susan.teacher) >> True
Что произойдет, если мы изменим атрибут teacher прямо в одном из случаев:
Это важно отметить: переменные экземпляров не нужно объявлять, они создаются всякий раз, когда им присваиваются, а переменные экземпляра переопределяют переменные класса. Это означает, что в экземпляре Tom teacher больше не ссылается на переменную класса, а на вновь созданную переменную экземпляра.
И, естественно, экземпляр Сьюзен не затронут:
tom.teacher >> Mr. Clark susan.teacher >> Mrs. Jones
Надеюсь, вы видите, как такое поведение может привести к путанице. По этой причине важно сохранять организованные имена переменных. Если переменная объявлена как переменная класса, она (обычно) не должна быть переопределена. Переменные экземпляра могут быть определены в очевидных местах, например, метод __init__. Часто хорошо придумать соглашение об именовании переменных. Например, методы класса должны быть глаголами, существительными переменных класса и существительными переменных экземпляра с префиксом «_».
Использование изменяемых объектов в качестве переменных класса
В связи с предыдущим шагом, будьте осторожны при использовании изменяемых объектов в качестве переменных класса. Вы можете быть удивлены поведением.
Представьте, что мы хотим получить список результатов тестов студента. Мы могли бы составить такой класс:
class Student: teacher = 'Mrs. Jones' test_scores = [] def __init__(self, name): self.name = name def add_score(self, score): self.test_scores.append(score)
У нас есть переменная класса для хранения баллов, и у нас есть метод класса для добавления баллов. Теперь давайте добавим несколько баллов.
tom = Student('Tom') susan = Student('Susan') tom.add_score(90) susan.add_score(100)
Можете ли вы угадать, какую ошибку мы только что сделали?
Да, test_scores — это переменная класса, а не переменная экземпляра. Каждый экземпляр просто добавляет значения в переменную класса. Мы действительно хотим, чтобы каждый экземпляр содержал свой собственный список test_scores.
Так что лучший класс может выглядеть так:
class Student: teacher = 'Mrs. Jones' def __init__(self, name): self.name = name self.test_scores = [] def add_score(self, score): self.test_scores.append(score)
И теперь наша проблема решена!
Заключение
Надеюсь, вы узнали разницу между переменными класса и экземпляра и что ожидать от каждой из них. Если я что-то упустил в этом руководстве или у вас есть отличные примеры путаницы переменных класса и экземпляра, пожалуйста, прокомментируйте ниже. Я был бы рад добавить их в это руководство!