Конструктор класса – метод __init__
В объектно-ориентированном программировании конструктором класса называют метод, который автоматически вызывается при создании объектов. Его также можно назвать конструктором объектов класса. Имя такого метода обычно регламентируется синтаксисом конкретного языка программирования. Так в Java имя конструктора класса совпадает с именем самого класса. В Python же роль конструктора играет метод __init__ .
В Python наличие пар знаков подчеркивания спереди и сзади в имени метода говорит о том, что он принадлежит к группе методов перегрузки операторов. Если подобные методы определены в классе, то объекты могут участвовать в таких операциях как сложение, вычитание, вызываться как функции и др.
При этом методы перегрузки операторов не надо вызывать по имени. Вызовом для них является сам факт участия объекта в определенной операции. В случае конструктора класса – это операция создания объекта. Так как объект создается в момент вызова класса по имени, то в этот момент вызывается метод __init__ .
Необходимость конструкторов связана с тем, что нередко объекты должны иметь собственные свойства сразу. Пусть имеется класс Person , объекты которого обязательно должны иметь имя и фамилию. Если класс будет описан подобным образом
class Person: def set_name(self, n, s): self.name = n self.surname = s
то создание объекта возможно без полей. Для установки имени и фамилии метод set_name нужно вызывать отдельно:
>>> from test import Person >>> p1 = Person() >>> p1.set_name("Bill", "Ross") >>> p1.name, p1.surname ('Bill', 'Ross')
В свою очередь, конструктор класса не позволит создать объект без обязательных полей:
class Person: def __init__(self, n, s): self.name = n self.surname = s p1 = Person("Sam", "Baker") print(p1.name, p1.surname)
Здесь при вызове класса в круглых скобках передаются значения, которые будут присвоены параметрам метода __init__ . Первый его параметр – self – ссылка на сам только что созданный объект.
Теперь, если мы попытаемся создать объект, не передав ничего в конструктор, то будет возбуждено исключение, и объект не будет создан:
>>> p1 = Person() Traceback (most recent call last): File "", line 1, in TypeError: __init__() missing 2 required positional arguments: 'n' and 's'
Однако бывает, что надо допустить создание объекта, даже если никакие данные в конструктор не передаются. В таком случае параметрам конструктора класса задаются значения по умолчанию:
class Rectangle: def __init__(self, w=0.5, h=1): self.width = w self.height = h def square(self): return self.width * self.height rec1 = Rectangle(5, 2) rec2 = Rectangle() rec3 = Rectangle(3) rec4 = Rectangle(h=4) print(rec1.square()) print(rec2.square()) print(rec3.square()) print(rec4.square())
10 0.5 3 2.0
Если класс вызывается без значений в скобках, то для параметров будут использованы их значения по умолчанию. Однако поля width и height будут у всех объектов.
Кроме того, конструктору вовсе не обязательно принимать какие-либо параметры, не считая self .
В других языка программирования, например в Java, классы могут содержать несколько конструкторов, которые между собой отличаются количеством параметром, а также, возможно, их типом. При создании объекта срабатывает тот конструктор, количество и типы параметров которого совпали с количеством и типами переданных в конструктор аргументов.
В Python создать несколько методов __init__ в классе можно, однако «рабочим» останется только последний. Он переопределит ранее определенные. Поэтому в Python в классах используется только один конструктор, а изменчивость количества передаваемых аргументов настраивается через назначение значений по-умолчанию.
Практическая работа. Конструктор и деструктор
Помимо конструктора объектов в языках программирования есть обратный ему метод – деструктор. Он вызывается, когда объект не создается, а уничтожается.
Это не значит, что сам деструктор уничтожает объект. В теле самого метода нет никаких инструкций по удалению экземпляра. Непосредственное удаление выполняется автоматически так называемым сборщиком мусора.
Деструктор (финализатор) в коде вашего класса следует использовать, когда при удалении объекта необходимо выполнить ряд сопутствующий действий, например, отправить сообщение, закрыть файл, разорвать соединение с базой данных.
В языке программирования Python объект уничтожается, когда исчезают все связанные с ним переменные или им присваивается другое значение, в результате чего связь со старым объектом теряется. Удалить переменную можно с помощью команды языка del . Также все объекты уничтожаются, когда программа завершает свою работу.
В классах Python функцию деструктора выполняет метод __del__ .
Напишите программу по следующему описанию:
- Есть класс Person , конструктор которого принимает три параметра (не учитывая self ) – имя, фамилию и квалификацию специалиста. Квалификация имеет значение заданное по умолчанию, равное единице.
- У класса Person есть метод, который возвращает строку, включающую в себя всю информацию о сотруднике.
- Класс Person содержит деструктор, который выводит на экран фразу «До свидания, мистер …» (вместо троеточия должны выводиться имя и фамилия объекта).
- В основной ветке программы создайте три объекта класса Person . Посмотрите информацию о сотрудниках и увольте самое слабое звено.
- В конце программы добавьте функцию input() , чтобы скрипт не завершился сам, пока не будет нажат Enter . Иначе вы сразу увидите как удаляются все объекты при завершении работы программы.
Курс с примерами решений практических работ:
pdf-версия
X Скрыть Наверх
Объектно-ориентированное программирование на Python
Язык Python
Язык python полноценно поддерживает объектно-ориентированную разработку. Минимальный класс в python можно создать следующим образом:
class NewGreatType: pass obj = NewGreatType() type(obj) #
Любой объект в python является объектом какого-либо класса:
type(1) # type(int) # type(NewGreatType) # type(type) #
Эти примеры показывают, что типы данных сами являются объектами класса type . Встроенная функция dir позволяет получить все атрибуты (поля и методы) объекта. Выведем для примера атрибуты объекта False класса bool :
dir(False) # ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', # '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', # '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', # '__getattribute__', '__getnewargs__', '__gt__', '__hash__', # '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', # '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', # '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', # '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', # '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', # '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', # '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', # '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', # 'as_integer_ratio', 'bit_length', 'conjugate', 'denominator', # 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
Довольно много для такого простого объекта. Попробуем вызвать метод __or__ :
False.__or__(False) # False False.__or__(True) # True
Вызов этого метода эквивалентен использованию оператора or . Мы обнаружили способ перегрузки операторов в python. Она выполняется с помощью определения «магических» методов, некоторые из которых мы рассмотрим ниже.
Поля и методы
Вспомним класс LorentzVector , с которым мы работали в разделе про классы в C++ и начнем писать его аналог на python:
class LorentzVector: """ Релятивистский вектор """ def __init__(self, t, x): """ x: может быть int, float или list """ self.t = t self.x = x def r2(self): """ Квадрат модуля пространственной компоненты """ if isinstance(self.x, (int, float)): return self.x**2 return sum(map(lambda a: a**2, self.x)) def inv(self): """ Релятивистский инвариант """ return self.t**2 - self.r2()
Метод __init__ является конструктором. Объект self ссылается на сам объект класса (аналог this в C++) и является обязательным первым аргументом всех нестатических методов, включая конструктор. В конструкторе мы определили два поля класса: self.x и self.y . Также мы определили два метода: r2 возвращает квадрат пространственной компоненты вектора, и inv возвращает релятивистский инвариант, соответствующий вектору.
Все поля и методы класса в python являются публичными. Разделение интерфейса и деталей реализации происходит на уровне соглашения об именах полей и методов: если атрибут не является частью интерфейса, то его имя должно начинаться с двух подчеркиваний, например: __internal_variable .
Проверим работу класса LorentzVector :
lv1 = LorentzVector(1, 0.5) lv1.t # 1 lv1.x # 0.5 lv1.r2() # 0.25 lv1.inv() # 0.75
lv2 = LorentzVector(1, [0.3, 0.4, 0.0]) lv2.t # 1 lv2.x # [0.3, 0.4, 0.0] lv2.r2() # 0.25 lv2.inv() # 0.75
Атрибуты могут определяться не только в конструкторе, но и в любом другом методе класса. Более того, атрибуты можно определять прямо в пользовательском коде:
lv = LorentzVector(1, 0.5) hasattr(lv, 'mass') # False lv.mass = 0.3 hasattr(lv, 'mass') # True
Атрибуты класса (статические атрибуты) определяются сразу после названия класса:
class LorentzVector: """ Релятивистский вектор """ speed_of_light = 2.99792458e10 # см / с # . LorentzVector.speed_of_light # 29979245800.0
Для задания статического метода необходимо использовать декоратор staticmethod :
class LorentzVector: # . @staticmethod def boost_vector(lv): """ Возвращает boost-вектор для данного вектора """ if isinstance(lv.x, (int, float)): return lv.x / lv.t return list(map(lambda x: x / lv.t, lv.x))
Как и следовало ожидать, статический метод не имеет аргумента self . Декораторы — это инструмент python, позволяющий менять поведение функций. Технически — это функция, которая принимает на вход некоторую функцию, и возвращает новую функцию с тем же набором аргументов.
С помощью декоратора property можно делать вызов методов, не имеющих аргументов, похожим на обращение к полю класса:
class LorentzVector: # . @property def r2(self): """ Квадрат модуля пространственной компоненты """ if isinstance(self.x, (int, float)): return self.x**2 return sum(map(lambda a: a**2, self.x)) @property def inv(self): """ Релятивистский инвариант """ return self.t**2 - self.r2()
lv1 = LorentzVector(1, 0.5) lv1.t # 1 lv1.x # 0.5 lv1.r2 # 0.25 lv1.inv # 0.75
Магические методы
Интеграция пользовательских классов в среду языка выполняется посредством определения специальных методов. Начнём с рассмотрения примера перегрузки арифметического оператора:
class LorentzVector: # . def __add__(self, rhs): """ Сложение двух векторов """ if isinstance(self.x, (int, float)): x_new = self.x + rhs.x else: x_new = list(map(lambda a: sum(a), zip(self.x, rhs.x))) return LorentzVector(self.t + rhs.t, x_new)
Аналогично выполняется перегрузка операторов вычитания ( __sub__ ), умножения ( __mul__ ), деления ( __div__ ), круглых скобок ( __call__ ), квадратных скобок ( __getitem__ ) и т.д.
Методы __str__ и __repr__ отвечают за текстовое представление объекта. Метод __str__ вызывается, когда объект передается в функцию print или в форматированную строку, и служит для «неформального» представления объекта. Метод __repr__ должен возвращать строку, которая содержит всю информацию о состоянии объекта и по которой объект может быть восстановлен. Если определен только метод __repr__ , то он будет вызываться в функции print вместо метода __str__ .
Если передать объект LorentzVector в функцию print , не определяя специальных методов, то мы получим что-то подобное:
lv = LorentzVector(1, 0.5) print(lv) # __main__.LorentzVector object at 0x7f50a36dfeb0>
Функция print вывела тип объекта и адрес, по которому он расположен в памяти.
Определим метод __repr__ :
class LorentzVector: # . def __repr__(relf): """ Текстовое представление вектора """ return f'LorentzVector [self.t>, self.x>]'
lv = LorentzVector(1, 0.5) print(lv) # LorentzVector [1, 0.5]
Мы рассмотрели лишь некоторые из доступных специальных методов. Рекомендуем ознакомиться с полным списком в документации.
Наследование
Язык python позволяет выполнять наследование классов. Класс-потомок имеет доступ ко всем полям и методам класса-предка. Все классы в python являются наследниками класса object . Об класса object наш класс LorentzVector наследует большинство своих атрибутов:
lv = LorentzVector(1, 0.5) isinstance(lv, object) # True dir(lv) # ['__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__', 'inv', 'mass', # 'r2', 'sum', 't', 'x']
Используем механизм наследования, чтобы реализовать тип релятивистского вектора иначе. Новый тип будет наследником именованного кортежа NamedTuple :
from typing import NamedTuple class FourVector(NamedTuple): # """ Релятивистский вектор """ t: float # такой синтаксис используется для задания r: list # полей кортежа и аннотации их типов @property def r2(self): """ Квадрат модуля пространственной компоненты """ return sum(map(lambda a: a**2, self.r)) @property def inv(self): """ Релятивистский инвариант """ return self.t**2 - self.r2() def __repr__(relf): """ Текстовое представление вектора """ return f'FourVector [self.t>, self.r>]'
Новая реализация яснее показывает структуру нашего типа данных. Для создания объекта FourVector необходимо задать значения полям t и r :
fv1 = FourVector(1, [0.3, 0.4, 0.0]) fv2 = FourVector(t=1, r=[0.3, 0.4, 0.0]) fv3 = FourVector(t=1, r=[0.5]) fv4 = FourVector(t=1, r=0.5) fv3.r2 # 0.25 fv4.r2 # TypeError: 'float' object is not iterable
При создании объекта fv4 мы нарушили соглашение и передали в поле r объект float вместо list . Это привело к ошибке при вызове метода r2 . При определении класса FourVector мы использовали аннотацию типов ( t: float ).
Больше информации о наследовании в python можно найти в документации.
Полиморфизм в python
Реализация полиморфизма в python сильно отличается от его реализации в C++. Полиморфизм в C++ реализуется с помощью инструментов наследования и шаблонов. Динамическая типизация python позволяет использовать гораздо более гибкие инструменты полиморфизма. Переменные, аргументы функций и атрибуты классов в python могут в разных контекстах иметь разные типы и даже менять тип со временем. Таким образом, все объекты в python изначально полиморфны.
В такой ситуации возникает вопрос о том как описывать ограничения на допустимые типы объектов. Здесь на помощь приходит принцип утиной типизации (duck typing), дословно состоящий в том, что «если что-то выглядит как утка и крякает как утка, значит это утка». Иными словами, если объект предоставляет необходимый интерфейс, то мы можем с ним работать вне зависимости от его типа. Для поддержки этого подхода в python реализованы инструменты для проверки свойств объектов:
# проверяет является ли obj объектом типа int или float isinstance(obj, (int, float)) # проверяет имеет ли obj атрибут norm hasattr(obj, 'norm') # является ли класс FourVector подклассом NamedTuple issubclass(FourVector, NamedTuple)
Столь гибкая типизация приводит к необходимости качественной документации кода. Хорошим стилем является описание всех контрактов функции или метода в его строке комментария. Значительно улучшает читаемость кода и аннотация типов.
Резюме
В этом разделе мы выполнили краткий обзор инструментов python, реализующих парадигму объектно-ориентированного программирования. Обсудили создание классов; определение полей и методов; статических полей и методов; определение специальных методов, позволяющих интегрировать тип данных в среду языка; кратко рассмотрели наследование классов и принципы реализации полиморфизма в python.
Концепция ООП в python не является основной, как в C++, однако средства ООП составляют важную часть языка, и их понимание необходимо для грамотной разработки на python, поскольку все типы объектов в python являются классами.
Источники
- docs.python.org/3/reference/datamodel
- docs.python.org/3/tutorial/classes
- docs.python.org/3/library/typing
- Python Inheritance
- Понимаем декораторы в Python’e, шаг за шагом (habr)
- Введение в аннотации типов Python (habr)
- Введение
- Настройка рабочей среды
- Язык C++
- Язык Python
- Основы синтаксиса языка python
- Строки
- Стандартные модули python, часть I
- ООП в python
- Стандартные модули II
- Итераторы и генераторы
- Вычисления с библиотекой numpy
- Визуализация данных с matplotlib
Несколько конструкторов с разным количеством аргументов
В данном случае можно создавать экземпляры класса только со вторым констуктором, в то время как запись x = a(42) вызовет ошибку.
Отслеживать
51.4k 86 86 золотых знаков 267 267 серебряных знаков 505 505 бронзовых знаков
задан 13 фев 2013 в 19:16
119 1 1 золотой знак 3 3 серебряных знака 10 10 бронзовых знаков4 ответа 4
Сортировка: Сброс на вариант по умолчанию
Если быть кратким то НЕТ.
Более детально посмотрите обсуждение вот ЗДЕСЬ. Там и варианты решений есть такие как использование необязательных или ключевых аргументов.
Отслеживать
3 4 4 бронзовых знака
ответ дан 13 фев 2013 в 19:21
3,724 14 14 серебряных знаков 16 16 бронзовых знаковВ Python’е перегрузок функций (а конструктор, по факту — это функция) нет в принципе. В вашем случае, вызывается всегда второй конструктор, ибо инструкция def означает «создать объект функции и присвоить этот объект написанному имени», то есть, сначала вы присваиваете имени __init__ одну функцию (с параметром b ), а затем — тому же имени — другую функцию, уже без параметра b .
Поведение, которого вы добиваетесь, можно получить, используя параметры по умолчанию, например:
def __init__(self, b=None): # Здесь лучше придумать что-то отличное от проверки на None # больше соответствующее вашей задаче. Возможно, вам просто подойдет # какое-то значение по умолчанию. if b is None: pass else: pass # . a = a() # b будет равно None по умолчанию b = a(42) # b будет равно 42Класс и объект в 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']