JavaRush /Курсы /Модуль 1: Python Core /Создание классов и объектов

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

Модуль 1: Python Core
9 уровень , 2 лекция
Открыта

3.1 Создание класса

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

Основные понятия

  • Класс: шаблон для создания объектов. Класс определяет атрибуты и методы, которые будут у объектов этого класса.
  • Объект: экземпляр класса. Объект обладает всеми атрибутами и методами, определёнными в классе.
  • Атрибут: переменная, связанная с классом или объектом.
  • Метод: функция, связанная с классом или объектом.

Атрибуты — это, по сути, внутренние переменные объекта или класса. Методы — это функции, определённые внутри класса. Эти термины пришли из ООП и используются наравне с функциями и переменными.

Для объявления (создания) нового класса используется ключевое слово class. Общий синтаксис этой операции выглядит так:


class ИмяКласса:
    переменная1 = значение1
    переменнаяN = значениеN
          
    def функция1(self):
        код функции
            
    def функцияM(self):
        код функции

В принципе, можно сказать, что класс — это небольшая программа (переменные + функции), помещённая в отдельную поименованную область — ИмяКласса.

После того как вы создали класс, вы можете создавать объекты (экземпляры) этого класса. Этот код выглядит ещё проще:


переменнаяХ = ИмяКласса()

Важно! Имена переменных и методов в Python принято писать с маленькой буквы. Имена классов — с большой. Также при написании имён классов не используются символы подчеркивания. Если имя класса должно состоять из нескольких слов, то каждое из них пишется с большой буквы.

Если вы хотите обратиться к переменной класса/объекта, то обычно этот код выглядит так:


переменнаяХ.переменная1 = 10
переменнаяХ.функцияM()       

Но тут не без нюансов, о которых ниже…

3.2 Работа с объектом

И класс, и экземпляр класса (объект класса) являются объектами, поэтому и у первого, и у второго могут быть свои переменные и методы.

Существуют два типа переменных:

  • Атрибут/Переменная/Поле класса (class property)
  • Атрибут/Переменная/Поле объекта (object property)

И целых три типа методов:

  • Метод/Функция класса (class method)
  • Метод/Функция объекта (instance method)
  • Статический метод (static method)

Методы отличаются способом своего объявления и тем, как они вызываются.

Методы объекта

При объявлении метода объекта в него нужно передать первый обязательный параметр — self. При вызове метода в этот параметр передаётся ссылка на объект (instance).


class MyClass:

    def instance_method(self):
        print(type(self))  # <class 'MyClass'>
                   

my_object = MyClass()
my_object.instance_method()
        

В примере выше, когда начала выполняться функция instance_method(), в параметр self была передана ссылка на объект my_object.

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

При объявлении метода класса в него тоже нужно передать первый обязательный параметр — cls. При вызове метода в этот параметр передаётся ссылка на класс (class object). Также метод класса нужно пометить декоратором classmethod, как в примере ниже:


class MyClass:
    def instance_method(self):
        print(type(self))  # <class 'MyClass'>
        
    @classmethod
    def class_method(cls):
        print(type(cls))  # <class 'type'>
                   

my_object = MyClass()
my_object.instance_method()
MyClass.class_method()
        

В примере выше, когда начала выполняться функция class_method(), в параметр cls была передана ссылка на класс MyClass.

Статический метод

При объявлении статического метода в него ничего не нужно передавать, но он и не сможет обращаться к внутренним данным класса. Также метод нужно пометить декоратором staticmethod, как в примере ниже:


class MyClass:
    def instance_method(self):
        print(type(self))  # <class 'MyClass'>
        
    @classmethod
    def class_method(cls):
        print(type(cls))  # <class 'type'>
        
    @staticmethod
    def static_method():
        return "Этот метод не зависит от экземпляра или класса"
                   
my_object = MyClass()
my_object.instance_method()
MyClass.class_method()
MyClass.static_method() 
        

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

3.3 Переменные класса

Переменные класса

Для того чтобы объявить переменную (атрибут) класса, её нужно просто объявить в любом месте внутри класса. Обычно это делают в самом начале, до объявления методов класса. Пример:


class MyClass:
    attribute = "Я атрибут класса"
        
    @classmethod
    def class_method(cls):
        print(cls.attribute)  # Я атрибут класса
                  
my_object = MyClass()
MyClass.class_method()

Если вы хотите прочитать или записать значение в переменную класса, то используйте объект cls.

В принципе, к переменной класса можно обратиться и через имя класса:


class MyClass:
    attribute = "Я атрибут класса"
        
    @classmethod
    def class_method(cls):
        print(MyClass.attribute)  # Я атрибут класса
                  
my_object = MyClass()

print(MyClass.attribute)  # Я атрибут класса

Переменные/поля объекта

Переменные объекта (instance) — это поля объекта self. Вы просто работаете с ними через self.name. Именно для этого объект self и передаётся в каждый метод объекта.

Пример:


class MyClass:
    attribute = "Я атрибут класса"
        
    def set_name(self, name):
        self.name = name
        
    def print_name(self):
        print(self.name)    
                 
my_object = MyClass()
my_object.set_name("Поле объекта по имени name") 
my_object.print_name()  # "Поле объекта по имени name"
        

Каждый раз, когда вы вызываете метод объекта, в качестве первого параметра (self) передаётся ссылка на объект, у которого вы и вызываете метод. Разные методы объекта могут обращаться к общим данным через использование объекта self.

2
Задача
Модуль 1: Python Core, 9 уровень, 2 лекция
Недоступна
Создаем объекты.
Создаем объекты.
2
Задача
Модуль 1: Python Core, 9 уровень, 2 лекция
Недоступна
Создаем классы.
Создаем классы.
Комментарии (24)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Maksym Уровень 16
28 октября 2025

claas Library:
    books = ["Python-Например","Python для начинающих"]

    def add_book(self, books):
        Library.books.append(books)



    def display_books(self):
        print("Список книг:")
        for book in Library.books:
            print("-", book) 


lib = Library()
lib.add_book("Python продвинутый уровень")
lib.display_books()"
shinobi Уровень 19
1 августа 2025
Немного пришлось поболтать с нейронкой, с которой автор и делал эту лекцию, чтобы понять что к чему. Она мне объяснила подробнее, я понял что к чему и за 5-10 минут сделал задачу. Сейчас я продемонстрирую рабочий ответ для второй задачи с пояснениями к каждой строчке, мб распутаю "узелки" в чьей-то голове, кто тоже прочитал лекцию но ему этого не хватило.

class Library:
    books = ["Граф Монте-Кристо", "Декстер: Тёмный пассажир", "Гарри Поттер и кубок огня"] # создаём класс, внутри которого лежит список с книгами, он нужен в классе, чтобы все функции(def) этого класса могли ссылаться на данный список


    def add_book(self, book): # создаём функцию, которая добавляет книгу. В функцию нужно передать self (чтобы она ссылалась на класс, и book (бук это просто имя от автора задачи, в программе "бук" это то, что передаст пользователь потом))
        self.books.append(book)   # ссылаемся на класс (self), затем на список в классе(books), затем метод добавления элемента в список (append),а передаем аргумент (book) (его ниже впишет пользователь) 


    def display_books(self): #создаём функцию, которая ссылается на свой класс (self)
        print("Список всех книг: ", self.books) #отображаем книги, ссылаемся на класс (self) и на список (books)

ppp = Library() # Создаём переменную, которая ссылается на наш класс
ppp.add_book(input("Введите книгу: ")) # Переменная выступает ссылкой на класс, вызываем нашу функцию (add_book), и передаём в нее параметр (в данном случае инпут с вводом строки, но можно и любой аргумент), строка принимает значение "book", так как вышше в функции мы указали, что она ссылается на себя(self), и имеет аргумент (book)
ppp.display_books() # Ccылаемся на класс и вызываем функцию display_books
Anatolii Lvov Уровень 28
24 июля 2025
Код работает без ошибок. класс Library с атрибутом books создан. Методы add_book(book) и display_books() созданы. объект класса Library создан. Книга добавляется и список выводится. Однако - Не выполнены все требования задачи. Почему? class Library: books = ["Война и мир", "Белая гвардия", "Ледокол"] def add_book(book): Library.books.append(book) def display_books(): print(Library.books) my_object = Library my_object.display_books() my_object.add_book("Отверженные") my_object.display_books()
shinobi Уровень 19
1 августа 2025
Вы забыли передать в функцию "display_books" параметр (self), чтобы функция ссылалась на класс.
Rmen Уровень 17
3 августа 2025
не на класс а на объект класса наверно
shinobi Уровень 19
4 августа 2025
на класс, не на объект класса
SWK Уровень 26
4 апреля 2025
Если я что-то из лекции понял, то в этом примере:

class MyClass:
    attribute = "Я атрибут класса"

    def set_name(self, name):
        self.name = name

    def print_name(self):
        print(self.name)

my_object = MyClass()
my_object.set_name("Поле объекта по имени name")
my_object.print_name()  # "Поле объекта по имени name"
во второй строчке должно объявляться поле name, а не attribute.
Ivan Уровень 59
11 мая 2025
Не обязательно. В питоне можно добавлять поля объектам прямо на лету. Что и делает метод set_name()

def set_name(self, name):
    self.name = name
Mr.Robot Уровень 21 Expert
8 марта 2025
Мне кажется целью второй задачи, как раз и было показать, как при помощи атрибутов и методов класса можно через один объект изменять состояние всех уже созданных экземпляров этого класса. Насколько это эффективно - с одной стороны и опасно - с другой, можно только восхититься, т.к. тем самым создается "сильная связь" и неизбежные сайд-эффекты, от которых ООП, как раз и призвано избавлять. Это же можно такую "свинью" в коде подложить, что унаследовавшие его разрабы точно добрым словом не вспомнят, да еще и поджидать будут в темном переулке )
SWK Уровень 26
4 апреля 2025
...это большой успех для задачи, в которой никто ничего не изменяет...
Александр Уровень 19 Expert
24 февраля 2025
Правильнее было бы решать вторую задачу через __init__, и такое решение предлагается в подсказке, но поскольку мы еще не проходили, валидатор принимает и простое решение. Зачем использовать __init__ ? Спасибо Николаю Мельнику за прекрасный разбор с примерами, почему без __init__ код работает неправильно. В простом варианте решения переменная books является переменной класса, а не переменной экземпляра. В результате чего, она доступна всем экземплярам класса, что и демонстрирует Николай. C __init__ переменная books становится индивидуальной для каждого экземпляра объекта, что более логично. Вот интересно, я слишком мудрю, видя глубокий смысл в решении таких задач, для углубленного понимания материала ? Или авторы просто не доработали еще задачи ? )))
Vanil'ka Уровень 25
7 августа 2025
Так вот зачем нужен конструктор класса! Спасибо, вы открыли мне глаза. Во всяких курсах постоянно говорили, что нужно создавать конструктор. А зачем он нужен? Никто не объяснял.
UnknownReboot Уровень 30
4 февраля 2025
1984
Dmitry Ryabov Уровень 23
3 февраля 2025
Тут нет необходимости в __init__, ни в одной из задач
Иван Уровень 12
21 сентября 2024
лекция про одно задачи про другое) что такое статическое методы и что такое методы класса в чем различаю не рассказывают, а задачи с решением через init но мы про это тоже не будем говорить)
Елена Уровень 55
13 октября 2024
я решила без init , все работает...
Муса Романюк Уровень 59
1 февраля 2025
Елена права! Задачу решил без init. С помощью метода класса. неуверен правильно ли это, но все засчиталось.
Семён Уровень 34
21 августа 2024
в правильных решениях задач указан __init__ о котором рассказывается только в следующей лекции🙃
13 февраля 2025
Тут очень интересная ситуация с этой задачей. Пройдусь по пунктам: 1) # Создайте класс Library с атрибутом books

class Library(object):
    books = ["j. Austen"]
13 февраля 2025
2). # Добавьте методы add_book(book) для добавления книги в библиотеку # и display_books() для вывода списка всех книг.

    def add_book(self, book):
        self.books.append(book)

    def display_books(self):
        print(self.books)

    @classmethod
    def display_books_(cls):
        print(cls.books)
метод класса - это уже от меня 3) Создаю 2 объекта, в каждый добавляю разные книги, и вывожу список книг у каждого объекта и у класса.:

library = Library()
library_1 = Library()

library.add_book("test")
library_1.add_book("ABC")

library.display_books()
library_1.display_books()
Library.display_books_()
Результат:

['j. Austen', 'test', 'ABC']
['j. Austen', 'test', 'ABC']
['j. Austen', 'test', 'ABC']
13 февраля 2025
Ситуация такая, что переменная self.books должна быть у каждого объекта своя. По факту - она общая, и это переменная cls.books 4) Если явно указать метод __init__, и в нем провести инициализацию переменной self.books, то всё работает корректно

 def __init__(self):
        self.books = []
Результат:

['test']
['ABC']
['j. Austen']
Остается сделать вывод, что все объекты класса, при создании, получают копии атрибутов класса внутри себя (self.копия_атрибута_класса), т.е. переманная внутри self, которая имеет такое же название, и ссылается на тот-же объект п памяти, что и атрибут класса (! Если не переопределен метод __init__, в котором эта переменная инициализируется новым объектом в памяти) Кто вкурсе - правильно ли я понял логику? В следующих лекциях это не обьясняется
14 февраля 2025
UPDATE! Думаю, в этой задаче изначально надо было использовать init метод, и создавать атрибуты для self, а не создавать атрибуты класса. Но на вопрос, поднятый мной, я все-же нашел ответ в 20-й лекции, и он связан с Порядком разрешения методов (MRO). Там, правда, обращение к атрибутам класса при наследовании..., но я думаю, что здесь похожая ситуация
Дмитрий Уровень 27
12 марта 2025
И да, и нет. Аттрибут класса наследуется всеми экземплярами, но независим и может меняться раздельно, если он не список. А вот список в аттрибуте класса создаётся один и меняется из любого экземпляра, поэтому надо быть осторожным со списками:

class Class1:
    attr1 = 'attribute1'
    attrl = [1, 2, 3]

obj1 = Class1()
obj2 = Class1()

obj1.attr2 = 'attribute2'
obj2.attr2 = 'attribute3'
obj1.attrl.append(4)
obj1.attr1 += 'opsss'

print(obj1.attr1, obj1.attr2, obj1.attrl) #Output: attribute1opsss attribute2 [1, 2, 3, 4]
print(obj2.attr1, obj2.attr2, obj2.attrl) #Output: attribute1 attribute3 [1, 2, 3, 4]

print(obj1.attr1 is obj2.attr1) #Output: False
print(obj1.attrl is obj2.attrl) #Output: True
Дмитрий Уровень 29
21 марта 2025
Нет просто автор попутал чутка. Просто не то слово написал, ведь надо было написать: Создайте класс Library с "полем объекта" books, а не с "атрибутом", и тогда было бы проще понять, что в его голове твориться когда он пишет т/з. Я бы не залез в комменты, если бы авторы внятно доносили свои мысли