Как много конструкторов в классе может иметь python
Перейти к содержимому

Как много конструкторов в классе может иметь python

  • автор:

Конструктор класса – метод __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__ .

Напишите программу по следующему описанию:

  1. Есть класс Person , конструктор которого принимает три параметра (не учитывая self ) – имя, фамилию и квалификацию специалиста. Квалификация имеет значение заданное по умолчанию, равное единице.
  2. У класса Person есть метод, который возвращает строку, включающую в себя всю информацию о сотруднике.
  3. Класс Person содержит деструктор, который выводит на экран фразу «До свидания, мистер …» (вместо троеточия должны выводиться имя и фамилия объекта).
  4. В основной ветке программы создайте три объекта класса Person . Посмотрите информацию о сотрудниках и увольте самое слабое звено.
  5. В конце программы добавьте функцию 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:

    Создание объекта с помощью класса 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

    Что происходит при создании объекта с помощью класса?

    При создании объекта класса 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 есть два похожих понятия, которые на самом деле отличаются:

    1. Атрибуты
    2. Переменные класса

    Стоит разобрать на практике:

    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'] 

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

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