Объект класса и конструктор класса в Python
Объект класса в Python представляет собой ИМЯ класса, созданного (определенного/записанного) в коде. Объекты класса поддерживают два вида операций: ссылки на атрибуты и создание экземпляров.
Ссылки на атрибуты используют стандартный синтаксис, используемый для всех ссылок на атрибуты в Python: obj.name . Допустимые имена атрибутов — это все имена, которые были определены в пространстве имен класса при создании объекта класса.
Итак, если определение класса выглядит так:
class MyClass: """Простой пример класса""" i = 12345 def f(self): return 'hello world' # `MyClass` - это объект класса >>> MyClass.i # 12345 >>> MyClass.f #
то имя MyClass — это объект класса, а MyClass.i и MyClass.f являются действительными ссылками на атрибуты класса, возвращая целое число и функциональный объект соответственно. Атрибуты объекта класса также могут быть присвоены, так что можно изменить значение MyClass.i путем операции присвоения. __doc__ также является допустимым атрибутом, возвращающим строку документации «Простой пример класса» , принадлежащую классу MyClass .
Экземпляр класса использует нотацию функций. Представьте, что объект класса — это функция без параметров, которая возвращает новый экземпляр класса. Пример ниже создает новый экземпляр класса и присваивает этот объект локальной переменной x :
x = MyClass() >>> x.i # 12345 >>> x.f() # 'hello world'
Конструктор класса __init__() .
Объекты классов обычно создают с экземплярами, настроенными на определенное начальное состояние. Для этого в классе Python определятся специальный метод «конструктор класса» с именем __init__() , который выполняется при создании экземпляра класса. Метод .__init__() принимает новый объект в качестве первого аргумента self .
class MyClass: """Простой пример класса""" i = 12345 def __init__(self): self.data = [] def f(self): return 'hello world'
Когда в классе определен метод .__init__() , то экземпляр класса автоматически вызывает .__init__() для вновь созданного экземпляра класса. Таким образом, в примере ниже, новый инициализированный экземпляр может быть получен с помощью:
>>> x = MyClass() >>> x.data # []
Метод __init__() может иметь аргументы для большей гибкости. В этом случае аргументы, переданные оператору создания класса, передаются в метод __init__() .
>>> class Complex: . def __init__(self, realpart, imagpart): . self.r = realpart . self.i = imagpart . >>> x = Complex(3.0, -4.5) >>> x.r, x.i (3.0, -4.5)
Важно отметить, что без учета self , аргументы метода .__init__() — это те же самые аргументы, которые передаются при вызове конструктора класса. Таким образом, сигнатура .__init__() определяет сигнатуру конструктора класса.
Имейте в виду, что конструктор класса .__init__() не должен явно возвращать ничего отличного от None , иначе будет вызываться исключение TypeError :
>>> class Complex: . def __init__(self, realpart, imagpart): . self.r = realpart . self.i = imagpart . return realpart + imagpart >>> x = Complex(3.0, -4.5) # Traceback (most recent call last): # File "", line 1, in # TypeError: __init__() should return None, not 'float'
В конструкторе класса .__init__() можно выполнить любое преобразование входных аргументов, чтобы правильно инициализировать атрибуты экземпляра. Например, если пользователи будут использовать класс Rectangle , то например, можно проверить предоставленные ширину и высоту, для того, чтобы убедиться в их верном значении:
>>> class Rectangle: . def __init__(self, width, height): . if not (isinstance(width, (int, float)) and width > 0): . raise ValueError(f"Необходима положительная ширина, получена: width>") . self.width = width . if not (isinstance(height, (int, float)) and height > 0): . raise ValueError(f"Необходима положительная высота, получена: height>") . self.height = height >>> rectangle = Rectangle(-21, 42) # Traceback (most recent call last): # File "", line 1, in # File "", line 4, in __init__ # ValueError: Необходима положительная ширина, получена: -21
Теперь предположим, что используется наследование для создания пользовательской иерархии классов и повторного использования некоторых функций в своем коде. Если подклассы предоставляют конструктор .__init__() , то он должен явно вызывать метод .__init__() базового класса с соответствующими аргументами, чтобы обеспечить правильную инициализацию экземпляров. Для этого необходимо использовать встроенную функцию super() , как в следующем примере:
>>> class Person: . def __init__(self, name, birth_date): . self.name = name . self.birth_date = birth_date >>> class Employee(Person): . def __init__(self, name, birth_date, position): . super().__init__(name, birth_date) . self.position = position >>> john = Employee("John Doe", "2001-02-07", "Разработчик Python") >>> john.name # 'John Doe' >>> john.birth_date # '2001-02-07' >>> john.position # 'Разработчик Python'
- ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
- Пространство имен и область видимости в классах
- Определение классов
- Объект класса и конструктор класса
- Создание экземпляра класса
- Метод экземпляра класса
- Что такое метод класса и зачем нужен
- Что такое статический метод в классах Python и зачем нужен
- Атрибуты класса и переменные экземпляра класса
- Кэширование методов экземпляра декоратором lru_cache
- Закрытые/приватные методы и переменные класса Python
- Наследование классов
- Множественное наследование классов
- Абстрактные классы
- Перегрузка методов в классе Python
- Что такое миксины и как их использовать
- Класс Python как структура данных, подобная языку C
- Создание пользовательских типов данных
- Специальные (магические) методы класса Python
- Базовая настройка классов Python магическими методами
- Настройка доступа к атрибутам класса Python
- Дескриптор класса для чайников
- Протокол дескриптора класса
- Практический пример дескриптора
- Использование метода .__new__() в классах Python
- Специальный атрибут __slots__ класса Python
- Специальный метод __init_subclass__ класса Python
- Определение метаклассов metaclass
- Эмуляция контейнерных типов в классах Python
- Другие специальные методы класса
- Как Python ищет специальные методы в классах
- Шаблон проектирования Фабрика и его реализация
Работа с конструкторами в Python
Конструктор в Python – это особый тип метода (функции), который используется для инициализации членов экземпляра класса.
В C ++ или Java конструктор имеет то же имя, что и его класс, в Python конструктор обрабатывается по-разному. Он используется для создания объекта.
Конструкторы бывают двух типов:
- Параметризованный конструктор
- Непараметрический конструктор
Определение конструктора выполняется, когда мы создаем объект этого класса. Конструкторы также проверяют, что у объекта достаточно ресурсов для выполнения любой задачи запуска.
Создание конструктора на Python
В Python метод __init __() имитирует конструктор класса. Этот метод вызывается при создании экземпляра класса. Он принимает ключевое слово self в качестве первого аргумента, который позволяет получить доступ к атрибутам или методу класса.
Мы можем передать любое количество аргументов во время создания объекта класса, в зависимости от определения __init __(). В основном он используется для инициализации атрибутов класса. У каждого класса должен быть конструктор, даже если он просто полагается на конструктор по умолчанию.
Рассмотрим следующий пример для инициализации атрибутов класса Employee при работе с конструкторами в Python.
class Employee: def __init__(self, name, id): self.id = id self.name = name def display(self): print("ID: %d nName: %s" % (self.id, self.name)) emp1 = Employee("John", 101) emp2 = Employee("David", 102) # accessing display() method to print employee 1 information emp1.display() # accessing display() method to print employee 2 information emp2.display()
ID: 101 Name: John ID: 102 Name: David
Подсчет количества объектов класса
Конструктор вызывается автоматически, когда мы создаем объект класса. Рассмотрим следующий пример.
class Student: count = 0 def __init__(self): Student.count = Student.count + 1 s1=Student() s2=Student() s3=Student() print("The number of students:",Student.count)
The number of students: 3
Непараметрический
Непараметрический конструктор используется, когда мы не хотим манипулировать значением, или конструктором, который имеет только self в качестве аргумента. Разберем на примере.
class Student: # Constructor - non parameterized def __init__(self): print("This is non parametrized constructor") def show(self,name): print("Hello",name) student = Student() student.show("John")
Параметризованный конструктор Python
У параметризованного конструктора есть несколько параметров вместе с самим собой.
class Student: # Constructor - parameterized def __init__(self, name): print("This is parametrized constructor") self.name = name def show(self): print("Hello",self.name) student = Student("John") student.show()
This is parametrized constructor Hello John
Конструктор Python по умолчанию
Когда мы не включаем конструктор в класс или забываем его объявить, он становится конструктором по умолчанию. Он не выполняет никаких задач, а инициализирует объекты. Рассмотрим пример.
class Student: roll_num = 101 name = "Joseph" def display(self): print(self.roll_num,self.name) st = Student() st.display()
101 Joseph
Более одного конструктора в одном классе
Давайте посмотрим на другой сценарий, что произойдет, если мы объявим два одинаковых конструктора в классе.
class Student: def __init__(self): print("The First Constructor") def __init__(self): print("The second contructor") st = Student()
The Second Constructor
В приведенном выше коде объект st вызвал второй конструктор, тогда как оба имеют одинаковую конфигурацию. Первый метод недоступен для объекта st. Внутренне объект класса всегда будет вызывать последний конструктор, если у класса есть несколько конструкторов.
Примечание. Перегрузка конструктора в Python запрещена.
Встроенные функции классов Python
Встроенные функции, определенные в классе, описаны в следующей таблице.
| SN | Функция | Описание |
|---|---|---|
| 1 | getattr(obj,name,default) | Используется для доступа к атрибуту объекта. |
| 2 | setattr(obj, name,value) | Она используется для установки определенного значения для определенного атрибута объекта. |
| 3 | delattr (obj, name) | Необходима для удаления определенного атрибута. |
| 4 | hasattr (obj, name) | Возвращает истину, если объект содержит определенный атрибут. |
class Student: def __init__(self, name, id, age): self.name = name self.id = id self.age = age # creates the object of the class Student s = Student("John", 101, 22) # prints the attribute name of the object s print(getattr(s, 'name')) # reset the value of attribute age to 23 setattr(s, "age", 23) # prints the modified value of age print(getattr(s, 'age')) # prints true if the student contains the attribute with name id print(hasattr(s, 'id')) # deletes the attribute age delattr(s, 'age') # this will give an error since the attribute age has been deleted print(s.age)
John 23 True AttributeError: 'Student' object has no attribute 'age'
Встроенные атрибуты класса
Наряду с другими атрибутами класс Python также содержит некоторые встроенные атрибуты класса, которые предоставляют информацию о классе.
Встроенные атрибуты класса приведены в таблице ниже.
| SN | Атрибут | Описание |
|---|---|---|
| 1 | __dict__ | Предоставляет словарь, содержащий информацию о пространстве имен класса. |
| 2 | __doc__ | Содержит строку с документацией класса. |
| 3 | __name__ | Используется для доступа к имени класса. |
| 4 | __module__ | Он используется для доступа к модулю, в котором определен этот класс. |
| 5 | __bases__ | Содержит кортеж, включающий все базовые классы. |
class Student: def __init__(self,name,id,age): self.name = name; self.id = id; self.age = age def display_details(self): print("Name:%s, ID:%d, age:%d"%(self.name,self.id)) s = Student("John",101,22) print(s.__doc__) print(s.__dict__) print(s.__module__)
Создание класса в Python
Эксперименты будем ставить на коде, который решает очень важную и ответственную задачу — выводит на экран вес фруктов. Делает он это, разумеется, с использованием ООП. Куда же без него во “взрослых” проектах?! И пускай от объявленного класса Fruit нет никакого проку, без него код выглядел бы слишком просто, а теперь в самый раз:
class Fruit(): pass apple = Fruit() apple.fruit_name = 'Яблоко' apple.weight_kg = 0.1 orange = Fruit() orange.fruit_name = 'Апельсин' orange.weight_kg = 0.3 print(apple.fruit_name, "| вес в граммах", apple.weight_kg * 1000) print(orange.fruit_name, "| вес в граммах", orange.weight_kg * 1000)
Скопируйте код к себе, запустите его в консоли:
$ python script.py Яблоко | вес в граммах 100.0 Апельсин | вес в граммах 300.0
Как это работает
Разберем что написано в этом коде. Первые две строки объявят новый класс Fruit :
class Fruit(): pass
Команда pass ничего не делает. Это заглушка, она нужна лишь потому, что Python требует внутри объявления класса написать хотя бы какой-то код. Написать здесь нечего, поэтому pass .
Следующая строка кода создаст новый объект — яблоко “apple”:
apple = Fruit()
Класс Fruit выступает шаблоном, который описывает свойства общие сразу для всех фруктов: и для яблок, и для апельсинов. Пока что шаблон пуст, и экземпляр apple ничего полезного от вызова Fruit не получит.
Следующие две строки добавят пару атрибутов к яблоку — название фрукта и его вес:
apple.fruit_name = 'Яблоко' apple.weight_kg = 0.1
Затем аналогичным образом по тому же шаблону — классу Fruit — будет создан еще один фрукт, на этот раз апельсин:
orange = Fruit() orange.fruit_name = 'Апельсин' orange.weight_kg = 0.3
Последние строчки кода пересчитают вес фрукта в граммах и выведут в консоль название и вес:
print(apple.fruit_name, "| вес в граммах", apple.weight_kg * 1000) print(orange.fruit_name, "| вес в граммах", orange.weight_kg * 1000)
Обязательные атрибуты
Можно заметить, что оба фрукта в программе имеют свойства с одинаковыми названиями — название fruit_name и вес weight_kg . Доработаем класс Fruit таким образом, чтобы все экземпляры созданные по этому шаблону обязательно имели свойства fruit_name и weight_kg .
Идея следующая. Пусть Python каждый раз после создания нового экземпляра фрукта сразу добавляет все нужные атрибуты. Добавим для этого новую функцию init_attrs :
# . объявление класса Fruit . def init_attrs(fruit, fruit_name='неизвестный фрукт', weight_kg=None): fruit.fruit_name = fruit_name fruit.weight_kg = weight_kg apple = Fruit() init_attrs(apple, 'Яблоко', 0.1) orange = Fruit() init_attrs(orange, 'Апельсин', 0.3) # . вызовы print .
Кода стало больше, но он стал надежнее. Добавляя новые фрукты: груши, вишню или абрикосы — вы точно не забудете указать вес и название. Вызовы функции init_attrs гарантирует, что все фрукты получат одинаковый набор обязательных атрибутов.
В Python коде функции похожие на init_attrs встречаются настолько часто, что для них есть стандартное название и специальный синтаксис. Переименуем функцию init_attrs в __init__ и переместим внутрь класса Fruit .
class Fruit(): def __init__(fruit, fruit_name='неизвестный фрукт', weight_kg=None): fruit.fruit_name = fruit_name fruit.weight_kg = weight_kg apple = Fruit('Яблоко', 0.1) orange = Fruit('Апельсин', 0.3) print(apple.fruit_name, "| вес в граммах", apple.weight_kg * 1000) print(orange.fruit_name, "| вес в граммах", orange.weight_kg * 1000)
Обратите внимание, что в программе нигде нет явного вызова __init__ . Python сам его вызовет выполняя эти строки кода:
apple = Fruit('Яблоко', 0.1) orange = Fruit('Апельсин', 0.3)
Теперь создавать фрукты по шаблону стало еще проще. Не надо писать вызовы функций, достаточно передать все аргументы для __init__ в класс Fruit .
Часто метод __init__ называют конструктором класса по аналогии с другими языками программирования. Это не совсем верно. Подробнее читайте на StackOverflow.
Добавим метод
Можно заметить что в коде пару раз встречается одинаковое выражение для расчета веса в граммах:
print(..., apple.weight_kg * 1000) print(..., orange.weight_kg * 1000)
Пересчет веса можно вынести в отдельную функцию:
# . объявление класса, __init__ для Fruit def get_weight_gr(fruit): return fruit.weight_kg * 1000 apple = Fruit('Яблоко', 0.1) orange = Fruit('Апельсин', 0.3) print(apple.fruit_name, "| вес в граммах", get_weight_gr(apple)) print(orange.fruit_name, "| вес в граммах", get_weight_gr(orange))
Функция get_weight_gr требует единственный аргумент — объект описывающий фрукт. Ей нет разницы, с каким именно фруктом работать, яблоком или апельсином. Главное, это чтобы фрукт был создан по стандартному шаблону — на основе класса Fruit . Python позволяет спрятать функцию get_weight_gr внутрь класса Fruit , чтобы эту связь между ними было не разорвать.
class Fruit(): def __init__(fruit, fruit_name='неизвестный фрукт', weight_kg=None): fruit.fruit_name = fruit_name fruit.weight_kg = weight_kg def get_weight_gr(fruit): return fruit.weight_kg * 1000
Функции, объявленные внутри класса называют методами и Python предлагает специальный набор инструментов для работы с ними.
По аналогии с функциями метод можно вызвать так:
Fruit.get_weight_gr(apple)
Однако, не вдаваясь в детали, принято делать так:
apple.get_weight_gr()
Python всегда помнит от какого класса был создан тот или иной объект, и знает что яблоко apple принадлежит к классу Fruit . От класса Fruit яблоко apple получило все его методы, включая get_weight_gr . Доступ к методам объекта получают через точку apple.get_weight_gr , а при вызове указывают первый аргумент функции, потому что его автоматически подставляет Python.
Теперь программа выглядит так:
class Fruit(): def __init__(fruit, fruit_name='неизвестный фрукт', weight_kg=None): fruit.fruit_name = fruit_name fruit.weight_kg = weight_kg def get_weight_gr(fruit): return fruit.weight_kg * 1000 apple = Fruit('Яблоко', 0.1) orange = Fruit('Апельсин', 0.3) print(apple.fruit_name, "| вес в граммах", apple.get_weight_gr()) print(orange.fruit_name, "| вес в граммах", orange.get_weight_gr())
Кто такой self
В Python есть стандартное название для первого атрибута метода. Вернемся к коду с фруктами и увидим там такое объявление методов:
class Fruit(): def __init__(fruit, fruit_name='неизвестный фрукт', weight_kg=None): ... def get_weight_gr(fruit): ...
В методах принято первый аргумент fruit называть self . Ход исполнения программы от этого не меняется, но другим программистам будет проще разобраться в коде:
class Fruit(): def __init__(self, fruit_name='неизвестный фрукт', weight_kg=None): self.fruit_name = fruit_name self.weight_kg = weight_kg def get_weight_gr(self): return self.weight_kg * 1000 apple = Fruit('Яблоко', 0.1) orange = Fruit('Апельсин', 0.3) print(apple.fruit_name, "| вес в граммах", apple.get_weight_gr()) print(orange.fruit_name, "| вес в граммах", orange.get_weight_gr())
Когда __init__ не нужен
Часто новый класс создается не на пустом месте, а наследуется от другого класса, предоставленного библиотекой. Например, так в Django выглядит добавление на сайт нового типа объектов — статей для блога:
from django.db.models import Model class Article(Model): pass
Сразу после объявления нового класса Article указан класс-предок Model . Из него будут позаимствованы все методы, включая готовый к использованию __init__ . Теперь внутри класса Article будет достаточно описать те методы, что отличают его от стандартного класса Model .
Когда аргументов много
Подобно другим функциям метод может принимать больше одного аргумента. Например:
class Fruit(): ... def get_title(self, upper_case, max_length): title = self.fruit_name if upper_case: title = title.upper() if max_length: title = title[:max_length] return title
Метод get_title принимает три аргумента. Так как это не просто функция, а метод, то первым аргументом обязан быть self . Его значение автоматически подставит Python. Остальные два аргумента upper_case и max_length должны быть вручную указаны при вызове метода:
apple.get_title(True, 20)
Попробуйте бесплатные уроки по Python
Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.
Переходите на страницу учебных модулей «Девмана» и выбирайте тему.
Класс и объект в Python
Python — это процедурно-ориентированный и одновременно объектно-ориентированный язык программирования.
Процедурно-ориентированный
«Процедурно-ориентированный» подразумевает наличие функций. Программист может создавать функции, которые затем используются в сторонних скриптах.
Объектно-ориентированный
«Объектно-ориентированный» подразумевает наличие классов. Есть возможность создавать классы, представляющие собой прототипы для будущих объектов.
Создание класса в Python
Синтаксис для написания нового класса:
class ClassName: 'Краткое описание класса (необязательно)' # Код .
- Для создания класса пишется ключевое слово class , его имя и двоеточие (:). Первая строчка в теле класса описывает его. (По желанию) получить доступ к этой строке можно с помощью ClassName.__doc__
- В теле класса допускается объявление атрибутов, методов и конструктора.
Атрибут:
Атрибут — это элемент класса. Например, у прямоугольника таких 2: ширина ( width ) и высота ( height ).
Метод:
- Метод класса напоминает классическую функцию, но на самом деле — это функция класса. Для использования ее необходимо вызывать через объект.
- Первый параметр метода всегда self (ключевое слово, которое ссылается на сам класс).
Конструктор:
- Конструктор — уникальный метод класса, который называется __init__ .
- Первый параметр конструктора во всех случаях self (ключевое слово, которое ссылается на сам класс).
- Конструктор нужен для создания объекта.
- Конструктор передает значения аргументов свойствам создаваемого объекта.
- В одном классе всегда только один конструктор.
- Если класс определяется не конструктором, Python предположит, что он наследует конструктор родительского класса.
# Прямоугольник. class Rectangle : 'Это класс Rectangle' # Способ создания объекта (конструктор) def __init__(self, width, height): self.width= width self.height = height def getWidth(self): return self.width def getHeight(self): return self.height # Метод расчета площади. def getArea(self): return self.width * self.height
Создание объекта с помощью класса Rectangle:
# Создаем 2 объекта: r1 & r2 r1 = Rectangle(10,5) r2 = Rectangle(20,11) print("r1.width token punctuation">, r1.width) print("r1.height token punctuation">, r1.height) print("r1.getWidth() token punctuation">, r1.getWidth()) print("r1.getArea() token punctuation">, r1.getArea()) print("-----------------") print("r2.width token punctuation">, r2.width) print("r2.height token punctuation">, r2.height) print("r2.getWidth() token punctuation">, r2.getWidth()) print("r2.getArea() token punctuation">, r2.getArea())

Что происходит при создании объекта с помощью класса?
При создании объекта класса Rectangle запускается конструктор выбранного класса, и атрибутам нового объекта передаются значения аргументов. Как на этом изображении:

Конструктор с аргументами по умолчанию
В других языках программирования конструкторов может быть несколько. В Python — только один. Но этот язык разрешает задавать значение по умолчанию.
Все требуемые аргументы нужно указывать до аргументов со значениями по умолчанию.
class Person: # Параметры возраста и пола имеют значение по умолчанию. def __init__(self, name, age=1, gender="Male"): self.name = name self.age = age self.gender= gender def showInfo(self): print("Name: ", self.name) print("Age: ", self.age) print("Gender: ", self.gender)
from person import Person # Создать объект Person. aimee = Person("Aimee", 21, "Female") aimee.showInfo() print(" --------------- ") # возраст по умолчанию, пол. alice = Person( "Alice" ) alice.showInfo() print(" --------------- ") # Пол по умолчанию. tran = Person("Tran", 37) tran.showInfo()

Сравнение объектов
В Python объект, созданный с помощью конструктора, занимает реальное место в памяти. Это значит, что у него есть точный адрес.
Если объект AA — это просто ссылка на объект BB , то он не будет сущностью, занимающей отдельную ячейку памяти. Вместо этого он лишь ссылается на местоположение BB .

Оператор == нужен, чтобы узнать, ссылаются ли два объекта на одно и то же место в памяти. Он вернет True , если это так. Оператор != вернет True , если сравнить 2 объекта, которые ссылаются на разные места в памяти.
from rectangle import Rectangle r1 = Rectangle(20, 10) r2 = Rectangle(20 , 10) r3 = r1 # Сравните r1 и r2 test1 = r1 == r2 # --> False # Сравните r1 и r3 test2 = r1 == r3 # --> True print ("r1 == r2 ? ", test1) print ("r1 == r3 ? ", test2) print (" -------------- ") print ("r1 != r2 ? ", r1 != r2) print ("r1 != r3 ? ", r1 != r3)

Атрибуты
В Python есть два похожих понятия, которые на самом деле отличаются:
- Атрибуты
- Переменные класса
Стоит разобрать на практике:
class Player: # Переменная класса minAge = 18 maxAge = 50 def __init__(self, name, age): self.name = name self.age = age
Атрибут
Объекты, созданные одним и тем же классом, будут занимать разные места в памяти, а их атрибуты с «одинаковыми именами» — ссылаться на разные адреса. Например:

from player import Player player1 = Player("Tom", 20) player2 = Player("Jerry", 20) print("player1.name token punctuation">, player1.name) print("player1.age token punctuation">, player1.age) print("player2.name token punctuation">, player2.name) print("player2.age token punctuation">, player2.age) print(" ------------ ") print("Assign new value to player1.age = 21 ") # Присвойте новое значение атрибуту возраста player1. player1.age = 21 print("player1.name token punctuation">, player1.name) print("player1.age token punctuation">, player1.age) print("player2.name token punctuation">, player2.name) print("player2.age token punctuation">, player2.age)

Python умеет создавать новые атрибуты для уже существующих объектов. Например, объект player1 и новый атрибут address .
from player import Player player1 = Player("Tom", 20) player2 = Player("Jerry", 20) # Создайте новый атрибут с именем «address» для player1. player1.address = "USA" print("player1.name token punctuation">, player1.name) print("player1.age token punctuation">, player1.age) print("player1.address token punctuation">, player1.address) print(" ------------------- ") print("player2.name token punctuation">, player2.name) print("player2.age token punctuation">, player2.age) # player2 е имеет атрибута 'address' (Error!!) print("player2.address token punctuation">, player2.address)
player1.name = Tom player1.age = 20 player1.address = USA ------------------- player2.name = Jerry player2.age = 20 Traceback (most recent call last): File "C:/Users/gvido/class.py", line 27, in print("player2.address атрибуты-функции"> Атрибуты функции Обычно получать доступ к атрибутам объекта можно с помощью оператора «точка» (например, player1.name). Но Python умеет делать это и с помощью функции.
Функция Описание getattr (obj, name[,default])Возвращает значение атрибута или значение по умолчанию, если первое не было указано hasattr (obj, name)Проверяет атрибут объекта — был ли он передан аргументом «name» setattr (obj, name, value)Задает значение атрибута. Если атрибута не существует, создает его delattr (obj, name)Удаляет атрибут
from player import Player player1 = Player("Tom", 20) # getattr(obj, name[, default]) print("getattr(player1,'name') token punctuation">, getattr(player1,"name")) print("setattr(player1,'age', 21): ") # setattr(obj,name,value) setattr(player1,"age", 21) print("player1.age token punctuation">, player1.age) # Проверка, что player1 имеет атрибут 'address'? hasAddress = hasattr(player1, "address") print("hasattr(player1, 'address') ? ", hasAddress) # Создать атрибут 'address' для объекта 'player1' print("Create attribute 'address' for object 'player1'") setattr(player1, 'address', "USA") print("player1.address token punctuation">, player1.address) # Удалить атрибут 'address'. delattr(player1, "address")
getattr(player1,'name') = Tom setattr(player1,'age', 21): player1.age = 21 hasattr(player1, 'address') ? False Create attribute 'address' for object 'player1' player1.address = USA
Встроенные атрибуты класса
Объекты класса — дочерние элементы по отношению к атрибутам самого языка Python. Таким образом они заимствуют некоторые атрибуты:
Атрибут
Описание
__dict__
Предоставляет данные о классе коротко и доступно, в виде словаря
__doc__
Возвращает строку с описанием класса, или None , если значение не определено
__class__
Возвращает объект, содержащий информацию о классе с массой полезных атрибутов, включая атрибут __name__
__module__
Возвращает имя «модуля» класса или __main__ , если класс определен в выполняемом модуле.
class Customer: 'Это класс Customer' def __init__(self, name, phone, address): self.name = name self.phone = phone self.address = address john = Customer("John",1234567, "USA") print ("john.__dict__ token punctuation">, john.__dict__) print ("john.__doc__ token punctuation">, john.__doc__) print ("john.__class__ token punctuation">, john.__class__) print ("john.__class__.__name__ token punctuation">, john.__class__.__name__) print ("john.__module__ token punctuation">, john.__module__)
john.__dict__ = john.__doc__ = Это класс Customer john.__class__ = john.__class__.__name__ = Customer john.__module__ = __main__
Переменные класса
Переменные класса в Python — это то же самое, что Field в других языках, таких как Java или С#. Получить к ним доступ можно только с помощью имени класса или объекта.
Для получения доступа к переменной класса лучше все-таки использовать имя класса, а не объект. Это поможет не путать «переменную класса» и атрибуты.

У каждой переменной класса есть свой адрес в памяти. И он доступен всем объектам класса.
from player import Player player1 = Player("Tom", 20) player2 = Player("Jerry", 20) # Доступ через имя класса. print ("Player.minAge token punctuation">, Player.minAge) # Доступ через объект. print("player1.minAge token punctuation">, player1.minAge) print("player2.minAge token punctuation">, player2.minAge) print(" ------------ ") print("Assign new value to minAge via class name, and print..") # Новое значение minAge через имя класса Player.minAge = 19 print("Player.minAge token punctuation">, Player.minAge) print("player1.minAge token punctuation">, player1.minAge) print("player2.minAge token punctuation">, player2.minAge)
Player.minAge = 18 player1.minAge = 18 player2.minAge = 18 ------------ Assign new value to minAge via class name, and print.. Player.minAge = 19 player1.minAge = 19 player2.minAge = 19
Составляющие класса или объекта
В Python присутствует функция dir , которая выводит список всех методов, атрибутов и переменных класса или объекта.
from player import Player # Вывести список атрибутов, методов и переменных объекта 'Player' print(dir(Player)) print("\n\n") player1 = Player("Tom", 20) player1.address ="USA" # Вывести список атрибутов, методов и переменных объекта 'player1' print(dir(player1))
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'maxAge', 'minAge'] ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'address', 'age', 'maxAge', 'minAge', 'name']
