Python classes and objects
Содержание:
- Содержание справочника по Python3:
- «Голое» исключение
- Полиморфизм в Python
- Что такое self?
- Примеры классов в Python и Java
- Увеличение объема памяти: полный успех
- Как выйти из группы Вконтакте с телефона
- Python NumPy
- GPON от МГТС версия 2016 — 2018 года: 16 комментариев
- «Приватные» поля класса
- Устойчивость объектов[править]
- Дескрипторы данных в классе (дескрипторы атрибутов).
- Замена сеттеров и геттеров на свойство Python
- Источники
- Определение конструктора для класса
Содержание справочника по Python3:
Создание и использование декораторов в Python.
По определению, декоратор — это функция, которая принимает другую функцию и расширяет поведение последней, не изменяя ее явно. На самом деле это не так. Декораторы предоставляют простой синтаксис для вызова функций высшего порядка.
Обработка ошибок и исключений в коде Python.
Синтаксические ошибки, это ошибки синтаксического анализа. Ошибки, обнаруженные во время выполнения, называются исключениями и не являются безусловно фатальными
Классы в языке Python.
Классы предоставляют средства объединения данных и функциональности вместе. Создание нового класса создает новый тип объекта, позволяя создавать новые экземпляры этого типа. Экземпляры класса также могут иметь методы, определяемые его классом, для из
Основные встроенные типы Python.
Основными встроенными типами являются числа, последовательности, отображения, классы, экземпляры и исключения.
Общие операции с последовательностями list, tuple, str в Python.
Общие операции с последовательностями поддерживаются большинством типов последовательностей, как изменяемых, так и неизменяемых. ABC `collections.abc.Sequence` предусмотрено, чтобы облегчить правильную реализацию этих операций на пользовательских тип
Операции с изменяемыми последовательностями в Python.
Здесь перечислены операции с изменяемыми последовательностями с их описанием и примерами использования в коде. Коллекция collections.abc.MutableSequence обеспечивает правильную реализацию этих операций на пользовательских типах последовательностей.
Операции с текстовыми строками str в Python.
По умолчанию все строки в Python-3 в Unicode. Строки — тип используются почти в каждой программе на Python
Уделите чуть больше внимание представленным здесь функциям и методам
Операции над словарями dict в Python.
Здесь представлены операции, которые поддерживает тип данных словарь dict. Пользовательские типы словарей также должны поддерживать представленные здесь операции со словарями.
Общие операции с множествами set и frozenset в Python.
Здесь перечислены все доступные операции с неизменяемыми множествами `frozenset`, с их описанием и примерами использования в коде.
Операции с изменяемым множеством set в Python.
Здесь перечислены операции с изменяемыми множеством `set` с их описанием и примерами использования в коде. Напоминаем, что множеством `set` поддерживают все операции доступные неизменяемым множествам `frozenset`.
Методы типов bytes и bytearray.
Байтовые строки `bytes` и объекты `bytearray` взаимодействуют не только с операндами одного типа, но и с любыми байтовыми объектами. Методы в байтовых строках `bytes` и `bytearray` объектах не принимают текстовые строки в качестве своих аргуме
Методы типа memoryview в Python.
Тип данных `memoryview` (буфер обмена) имеет несколько, представленных ниже методов класса `memoryview()`.
Методы файлового объекта/потока в Python.
Прежде чем вы сможете прочитать или написать файл, вы должны открыть его с помощью встроенной функции `open()`. Эта функция создает `file object`, который будет использоваться для вызова методов, которые представлены ниже.
Встроенные функции Python.
Интерпретатор Python имеет ряд встроенных функций и классов, которые всегда доступны. Они перечислены здесь в алфавитном порядке, с их описанием и примерами применения в коде.
Встроенные исключения в интерпретатор Python.
Встроенные исключения
«Голое» исключение
Есть еще один способ поймать ошибку:
Python
try:
1 / 0
except:
print(«You cannot divide by zero!»)
1 |
try 1 except print(«You cannot divide by zero!») |
Но мы его не рекомендуем. На жаргоне Пайтона, это известно как голое исключение, что означает, что будут найдены вообще все исключения. Причина, по которой так делать не рекомендуется, заключается в том, что вы не узнаете, что именно за исключение вы выловите. Когда у вас возникло что-то в духе ZeroDivisionError, вы хотите выявить фрагмент, в котором происходит деление на ноль. В коде, написанном выше, вы не можете указать, что именно вам нужно выявить. Давайте взглянем еще на несколько примеров:
Python
my_dict = {«a»:1, «b»:2, «c»:3}
try:
value = my_dict
except KeyError:
print(«That key does not exist!»)
1 |
my_dict={«a»1,»b»2,»c»3} try value=my_dict»d» exceptKeyError print(«That key does not exist!») |
Python
my_list =
try:
my_list
except IndexError:
print(«That index is not in the list!»)
1 |
my_list=1,2,3,4,5 try my_list6 exceptIndexError print(«That index is not in the list!») |
В первом примере, мы создали словарь из трех элементов. После этого, мы попытались открыть доступ ключу, которого в словаре нет. Так как ключ не в словаре, возникает KeyError, которую мы выявили. Второй пример показывает список, длина которого состоит из пяти объектов. Мы попытались взять седьмой объект из индекса.
Помните, что списки в Пайтоне начинаются с нуля, так что когда вы говорите 6, вы запрашиваете 7. В любом случае, в нашем списке только пять объектов, по этой причине возникает IndexError, которую мы выявили. Вы также можете выявить несколько ошибок за раз при помощи одного оператора. Для этого существует несколько различных способов. Давайте посмотрим:
Python
my_dict = {«a»:1, «b»:2, «c»:3}
try:
value = my_dict
except IndexError:
print(«This index does not exist!»)
except KeyError:
print(«This key is not in the dictionary!»)
except:
print(«Some other error occurred!»)
1 |
my_dict={«a»1,»b»2,»c»3} try value=my_dict»d» exceptIndexError print(«This index does not exist!») exceptKeyError print(«This key is not in the dictionary!») except print(«Some other error occurred!») |
Это самый стандартный способ выявить несколько исключений. Сначала мы попробовали открыть доступ к несуществующему ключу, которого нет в нашем словаре. При помощи try/except мы проверили код на наличие ошибки KeyError, которая находится во втором операторе except
Обратите внимание на то, что в конце кода у нас появилась «голое» исключение. Обычно, это не рекомендуется, но вы, возможно, будете сталкиваться с этим время от времени, так что лучше быть проинформированным об этом
Кстати, также обратите внимание на то, что вам не нужно использовать целый блок кода для обработки нескольких исключений. Обычно, целый блок используется для выявления одного единственного исключения. Изучим второй способ выявления нескольких исключений:
Python
try:
value = my_dict
except (IndexError, KeyError):
print(«An IndexError or KeyError occurred!»)
1 |
try value=my_dict»d» except(IndexError,KeyError) print(«An IndexError or KeyError occurred!») |
Обратите внимание на то, что в данном примере мы помещаем ошибки, которые мы хотим выявить, внутри круглых скобок. Проблема данного метода в том, что трудно сказать какая именно ошибка произошла, так что предыдущий пример, мы рекомендуем больше чем этот
Зачастую, когда происходит ошибка, вам нужно уведомить пользователя, при помощи сообщения.
В зависимости от сложности данной ошибки, вам может понадобиться выйти из программы. Иногда вам может понадобиться выполнить очистку, перед выходом из программы. Например, если вы открыли соединение с базой данных, вам нужно будет закрыть его, перед выходом из программы, или вы можете закончить с открытым соединением. Другой пример – закрытие дескриптора файла, к которому вы обращаетесь. Теперь нам нужно научиться убирать за собой. Это очень просто, если использовать оператор finally.
Полиморфизм в Python
Это концепция, при которой функция может принимать несколько форм в зависимости от количества аргументов или типа аргументов, переданных функции.
В приведенном выше примере ключевое слово super используется для вызова метода родительского класса. Оба класса имеют метод show_salary. В зависимости от типа объекта, который выполняет вызов этой функции, выходные данные различаются.
Python также имеет встроенные функции, работающие с полиморфизмом. Одним из самых простых примеров является функция print в Python.
Вывод будет таким:
В приведенном выше фрагменте кода:
- Параметр конечного ключевого слова изменил работу функции print. Следовательно, «Привет!» не заканчивалось концом строки.
- len () в третьей строке возвращает int. Печать распознает тип данных и неявно преобразует его в строку и выводит его на консоль.
Что такое self?
Классам нужен способ, что ссылаться на самих себя. Это не из разряда нарциссичного отношения со стороны класса. Это способ сообщения между экземплярами. Слово self это способ описания любого объекта, буквально. Давайте взглянем на пример, который мне кажется наиболее полезным, когда я сталкиваюсь с чем-то новым и странным:
Добавьте этот код в конец класса, который вы написали ранее и сохраните:
Python
class Vehicle(object):
«»»docstring»»»
def __init__(self, color, doors, tires):
«»»Constructor»»»
self.color = color
self.doors = doors
self.tires = tires
def brake(self):
«»»
Stop the car
«»»
return «Braking»
def drive(self):
«»»
Drive the car
«»»
return «I’m driving!»
if __name__ == «__main__»:
car = Vehicle(«blue», 5, 4)
print(car.color)
truck = Vehicle(«red», 3, 6)
print(truck.color)
1 |
classVehicle(object) «»»docstring»»» def__init__(self,color,doors,tires) «»»Constructor»»» self.color=color self.doors=doors self.tires=tires defbrake(self) «»» Stop the car return»Braking» defdrive(self) «»» Drive the car return»I’m driving!» if__name__==»__main__» car=Vehicle(«blue»,5,4) print(car.color) truck=Vehicle(«red»,3,6) print(truck.color) |
Условия оператора if в данном примере это стандартный способ указать Пайтону на то, что вы хотите запустить код, если он выполняется как автономный файл. Если вы импортировали свой модуль в другой скрипт, то код, расположенный ниже проверки if не заработает. В любом случае, если вы запустите этот код, вы создадите два экземпляра класса автомобиля (Vehicle): класс легкового и класс грузового. Каждый экземпляр будет иметь свои собственные атрибуты и методы. Именно по этому, когда мы выводи цвета каждого экземпляра, они и отличаются друг от друга. Причина в том, что этот класс использует аргумент self, чтобы указать самому себе, что есть что. Давайте немного изменим класс, чтобы сделать методы более уникальными:
Python
class Vehicle(object):
«»»docstring»»»
def __init__(self, color, doors, tires, vtype):
«»»Constructor»»»
self.color = color
self.doors = doors
self.tires = tires
self.vtype = vtype
def brake(self):
«»»
Stop the car
«»»
return «%s braking» % self.vtype
def drive(self):
«»»
Drive the car
«»»
return «I’m driving a %s %s!» % (self.color, self.vtype)
if __name__ == «__main__»:
car = Vehicle(«blue», 5, 4, «car»)
print(car.brake())
print(car.drive())
truck = Vehicle(«red», 3, 6, «truck»)
print(truck.drive())
print(truck.brake())
1 |
classVehicle(object) «»»docstring»»» def__init__(self,color,doors,tires,vtype) «»»Constructor»»» self.color=color self.doors=doors self.tires=tires self.vtype=vtype defbrake(self) «»» Stop the car return»%s braking»%self.vtype defdrive(self) «»» Drive the car return»I’m driving a %s %s!»%(self.color,self.vtype) if__name__==»__main__» car=Vehicle(«blue»,5,4,»car») print(car.brake()) print(car.drive()) truck=Vehicle(«red»,3,6,»truck») print(truck.drive()) print(truck.brake()) |
В этом примере мы передаем другой параметр, чтобы сообщить классу, какой тип транспортного средства мы создаем. После этого мы вызываем каждый метод для каждого экземпляра. Если вы запустите данный код, вы получите следующий вывод:
Python
car braking
I’m driving a blue car!
I’m driving a red truck!
truck braking
1 |
car braking I’m driving a blue car! I’mdrivingared truck! truck braking |
Это показывает, как экземпляр отслеживает свой аргумент self. Вы также могли заметить, что мы можем переместить переменные атрибутов из метода __init__ в другие методы. Это возможно потому, что все эти атрибуты связанны с аргументом self. Если бы мы этого не сделали, переменные были бы вне области видимости в конце метода __init__ .
Примеры классов в Python и Java
Для начала давайте реализуем простейший класс в Python и Java, чтобы проиллюстрировать некоторые отличия в этих языках, и будем постепенно вносить в этот класс изменения.
Представим, что у нас есть следующее определение класса Car в Java:
Имя исходного Java-файла должно соответствовать имени хранящегося в нем класса, поэтому мы обязаны назвать файл Car.java. Каждый Java-файл может содержать только один публичный класс.
Такой же класс в Python будет выглядеть так:
В Python вы можете объявить класс где угодно и когда угодно. Сохраним этот файл как car.py.
Используя эти классы как основу, продолжим исследование основных компонентов классов и объектов.
Увеличение объема памяти: полный успех
Как выйти из группы Вконтакте с телефона
Если вы зашли на сайт vk.com с мобильного браузера, то выйти из группы можно точно так же, как и в первом способе, описанном выше.
Если же вы пользуетесь официальным приложением, тогда:
- В левой менюшке выбираем «Группы»;
- Листаем и выбираем любое сообщество;
- Нажимаем на сенсорную кнопку вашего смартфона, которая чуть ниже дисплея (процентов 95, что левая, если нет, то пишем в комментариях какая));
- Появится несколько вариантов, один которых «Покинуть сообщество»;
- Profit!!!
Сегодня мы узнали как быстро и разом или постепенно и по выбору, из нескольких или всех сразу, автоматически или вручную можно выйти из групп социальной сети Вконтакте. Надеюсь вы нашли себе способ по душе и по настроению, а теперь снова в бой, «захламлять» свою страничку ВК.
Python NumPy
NumPy IntroNumPy Getting StartedNumPy Creating ArraysNumPy Array IndexingNumPy Array SlicingNumPy Data TypesNumPy Copy vs ViewNumPy Array ShapeNumPy Array ReshapeNumPy Array IteratingNumPy Array JoinNumPy Array SplitNumPy Array SearchNumPy Array SortNumPy Array FilterNumPy Random
Random Intro
Data Distribution
Random Permutation
Seaborn Module
Normal Distribution
Binomial Distribution
Poisson Distribution
Uniform Distribution
Logistic Distribution
Multinomial Distribution
Exponential Distribution
Chi Square Distribution
Rayleigh Distribution
Pareto Distribution
Zipf Distribution
NumPy ufunc
ufunc Intro
ufunc Create Function
ufunc Simple Arithmetic
ufunc Rounding Decimals
ufunc Logs
ufunc Summations
ufunc Products
ufunc Differences
ufunc Finding LCM
ufunc Finding GCD
ufunc Trigonometric
ufunc Hyperbolic
ufunc Set Operations
GPON от МГТС версия 2016 — 2018 года: 16 комментариев
«Приватные» поля класса
Вы обратили внимание, что в нашем классе некоторые атрибуты начинаются с нижнего подчеркивания? Это одно из множества соглашений принятых в сообществе разработчиков на языке Python, согласно которому «приватные» атрибуты должны начинаться с одного символа нижнего подчеркивания. Давайте создадим нового пользователя:. Допустим, что мы хотим изменить пароль (или адрес электронной почты) и делаем это через прямое обращение к атрибуту:
Допустим, что мы хотим изменить пароль (или адрес электронной почты) и делаем это через прямое обращение к атрибуту:
Почему пароль не прошел проверку? Мы изменили значение атрибута напрямую, не используя функцию , таким образом, мы сохранили пароль в открытом виде. В свою очередь функция хеширует переданный ей пароль в качестве аргумента и затем сравнивает его с паролем, который хранился в атрибуте .
Note
Больше про нижние подчеркивания можно узнать тут.
Устойчивость объектов[править]
Объекты всегда имеют своё представление в памяти компьютера и их время жизни не больше времени работы программы. Однако зачастую необходимо сохранять данные между запусками приложения и/или
передавать их на другие компьютеры.
Одним из решений этой проблемы является устойчивость объектов (англ. object persistence) которая достигается с помощью хранения представлений объектов (сериализацией) в виде байтовых последовательностей и их последующего восстановления (десериализация).
Модуль является наиболее простым способом «консервирования» объектов в Python.
Следующий пример показывает, как работает сериализация и десериализация:
# сериализация >>> import pickle >>> p = set() >>> pickle.dumps(p) 'c__builtin__\nset\np0\n((lp1\nI8\naI1\naI2\naI3\naI5\natp2\nRp3\n.' # де-сериализация >>> import pickle >>> p = pickle.loads('c__builtin__\nset\np0\n((lp1\nI8\naI1\naI2\naI3\naI5\natp2\nRp3\n.') >>> print p set()
Получаемая при сериализации строка может быть передана по сети, записана в файл или специальное хранилище объектов, а позже — прочитана. Сериализации поддаются не все объекты. Некоторые объекты (например, классы и функции) представляются своими именами, поэтому для десериализации требуется наличие тех же самых классов. Нужно отметить, что нельзя десериализовать данные из непроверенных
источников с помощью модуля , так как при этом возможны практически любые
действия на локальной системе. При необходимости обмениваться данными по незащищенным каналам
или с ненадежными источниками можно воспользоваться другими модулями для сериализации.
В основе сериализации объекта стоит представление его состояния. По умолчанию состояние объекта — это все, что записано в его полях. Пользовательские классы могут управлять сериализацией, предоставляя состояние объекта явным образом (методы , и др.).
На стандартном для Python механизме сериализации построена работа модуля (shelve (англ. глаг.) — ставить на полку; сдавать в архив). Модуль предоставляет функцию
. Объект, который она возвращает, работает аналогично словарю, но объекты сериализуются и сохраняются в файле:
>>> import shelve >>> s = shelve.open("myshelve.bin") >>> s'abc' = 1, 2, 3 >>> s.close() # ..... >>> s = shelve.open("myshelve.bin") >>> s'abc' 1, 2, 3
Сериализация — не единственная возможная, и подходит не всегда. Для сериализации, не зависящей от языка программирования, можно использовать, например, XML.
Дескрипторы данных в классе (дескрипторы атрибутов).
Вызов функции — это краткий способ построения дескриптора данных, который запускает вызовы функций при доступе к атрибуту.
Его подпись:
property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
В документации показано типичное использование для определения управляемого атрибута :
class C def getx(self): return self.__x def setx(self, value): self.__x = value def delx(self): del self.__x x = property(getx, setx, delx, "I'm the 'x' property.")
Чтобы увидеть, как функция реализована с точки зрения , вот чистый эквивалент на Python:
class Property "Emulate PyProperty_Type() in Objects/descrobject.c" def __init__(self, fget=None, fset=None, fdel=None, doc=None): self.fget = fget self.fset = fset self.fdel = fdel if doc is None and fget is not None doc = fget.__doc__ self.__doc__ = doc def __get__(self, obj, objtype=None): if obj is None return self if self.fget is None raise AttributeError("unreadable attribute") return self.fget(obj) def __set__(self, obj, value): if self.fset is None raise AttributeError("can't set attribute") self.fset(obj, value) def __delete__(self, obj): if self.fdel is None raise AttributeError("can't delete attribute") self.fdel(obj) def getter(self, fget): return type(self)(fget, self.fset, self.fdel, self.__doc__) def setter(self, fset): return type(self)(self.fget, fset, self.fdel, self.__doc__) def deleter(self, fdel): return type(self)(self.fget, self.fset, fdel, self.__doc__)
Встроенная функция помогает всякий раз, когда пользовательский интерфейс предоставляет доступ к атрибутам, а затем последующие изменения требуют вмешательства метода.
Например, класс электронных таблиц может предоставлять доступ к значению ячейки через . Последующие усовершенствования программы требуют, чтобы ячейка пересчитывалась при каждом доступе, но программист не хочет влиять на существующий клиентский код, напрямую обращающийся к атрибуту. Решение состоит в том, чтобы обернуть доступ к атрибуту в дескриптор данных свойства:
class Cell . . . def getvalue(self): "Recalculate the cell before returning value" self.recalc() return self._value value = property(getvalue)
Классно, неправда ли?
Замена сеттеров и геттеров на свойство Python
Давайте представим, что у нас есть код, который написал кто-то, кто не очень понимает Python. Как и я, вы скорее всего, видели такого рода код ранее:
Python
# -*- coding: utf-8 -*-
from decimal import Decimal
class Fees(object):
«»»»»»
def __init__(self):
«»»Конструктор»»»
self._fee = None
def get_fee(self):
«»»
Возвращаем текущую комиссию
«»»
return self._fee
def set_fee(self, value):
«»»
Устанавливаем размер комиссии
«»»
if isinstance(value, str):
self._fee = Decimal(value)
elif isinstance(value, Decimal):
self._fee = value
1 |
# -*- coding: utf-8 -*- fromdecimalimportDecimal classFees(object) «»»»»» def__init__(self) «»»Конструктор»»» self._fee=None defget_fee(self) «»» Возвращаем текущую комиссию returnself._fee defset_fee(self,value) «»» Устанавливаем размер комиссии ifisinstance(value,str) self._fee=Decimal(value) elifisinstance(value,Decimal) self._fee=value |
Для использования этого класса, нам нужно использовать сеттеры и геттеры, которые определены как:
Python
f = Fees()
f.set_fee(«1»)
print(f.get_fee()) # Decimal(‘1’)
1 |
f=Fees() f.set_fee(«1») print(f.get_fee())# Decimal(‘1’) |
Если вам нужно добавить обычную точечную нотацию атрибутов в данный код без выведения из строя всех приложений в этой части кода, вы можете сделать это очень просто, добавив свойство:
Python
# -*- coding: utf-8 -*-
from decimal import Decimal
class Fees(object):
«»»»»»
def __init__(self):
«»»Конструктор»»»
self._fee = None
def get_fee(self):
«»»
Возвращаем текущую комиссию
«»»
return self._fee
def set_fee(self, value):
«»»
Устанавливаем размер комиссии
«»»
if isinstance(value, str):
self._fee = Decimal(value)
elif isinstance(value, Decimal):
self._fee = value
fee = property(get_fee, set_fee)
1 |
# -*- coding: utf-8 -*- fromdecimalimportDecimal classFees(object) «»»»»» def__init__(self) «»»Конструктор»»» self._fee=None defget_fee(self) «»» Возвращаем текущую комиссию returnself._fee defset_fee(self,value) «»» Устанавливаем размер комиссии ifisinstance(value,str) self._fee=Decimal(value) elifisinstance(value,Decimal) self._fee=value fee=property(get_fee,set_fee) |
Мы добавили одну строк в конце этого кода. Теперь мы можем делать что-то вроде этого:
Python
f = Fees()
f.set_fee(«1»)
print(f.fee) # Decimal(‘1’)
f.fee = «2»
print( f.get_fee() ) # Decimal(‘2’)
1 |
f=Fees() f.set_fee(«1») print(f.fee)# Decimal(‘1’) f.fee=»2″ print(f.get_fee())# Decimal(‘2’) |
Как мы видим, когда мы используем свойство таким образом, это позволяет свойству fee настраивать и получать значение без поломки наследуемого кода. Давайте перепишем этот код с использованием декоратора property, и посмотрим, можем ли мы получить его для разрешения установки.
Python
# -*- coding: utf-8 -*-
from decimal import Decimal
class Fees(object):
«»»»»»
def __init__(self):
«»»Конструктор»»»
self._fee = None
@property
def fee(self):
«»»
Возвращаем текущую комиссию — геттер
«»»
return self._fee
@fee.setter
def fee(self, value):
«»»
Устанавливаем размер комиссии — сеттер
«»»
if isinstance(value, str):
self._fee = Decimal(value)
elif isinstance(value, Decimal):
self._fee = value
if __name__ == «__main__»:
f = Fees()
1 |
# -*- coding: utf-8 -*- fromdecimalimportDecimal classFees(object) «»»»»» def__init__(self) «»»Конструктор»»» self._fee=None @property deffee(self) «»» Возвращаем текущую комиссию — геттер returnself._fee @fee.setter deffee(self,value) «»» Устанавливаем размер комиссии — сеттер ifisinstance(value,str) self._fee=Decimal(value) elifisinstance(value,Decimal) self._fee=value if__name__==»__main__» f=Fees() |
Данный код демонстрирует, как создать сеттер для свойства fee. Вы можете делать это, декорируя второй метод, который также называется fee с декоратором, под названием <@fee.setter>. Сеттер будет вызван, когда вы сделаете что-то вроде следующего:
Python
f = Fees()
f.fee = «1»
1 |
f=Fees() f.fee=»1″ |
Если вы взгляните на подписи под свойством, то это будут fget, fset, fdel и doc в качестве аргументов. Вы можете создать другой декорируемый метод, используя то же название связи с функцией delet при помощи <@fee.deleter*>*, если вы хотите поймать команду **del для атрибута.
Источники
Определение конструктора для класса
Если вы заметили реализацию класса Employee, невозможно установить значение employee_id. Мы можем определить отдельный метод для установки значения employee_id. Но это обязательное свойство объекта Employee. Лучшее место для установки этих свойств — через конструктор.
Давайте продолжим и создадим конструктор для класса Employee. Мы ожидаем, что вызывающая программа передаст значение employee_id в качестве аргумента.
class Employee: def __init__(self, i): self.employee_id = i def work(self): print(f'{self.employee_id} is working') emp = Employee(100) emp.work()
Выход:
Примечание: предыдущий код для создания объекта Employee теперь не будет работать, потому что конструктор Employee ожидает аргумент. Если мы вызовем , он вызовет ошибку TypeError: в init() отсутствует 1 обязательный позиционный аргумент: ‘id’.
Можем ли мы иметь несколько конструкторов?
В отличие от других популярных объектно-ориентированных языков программирования, Python не поддерживает перегрузку методов и конструкторов.
Однако, если мы определим несколько конструкторов в классе, это не вызовет никаких ошибок. Последний конструктор перезапишет ранее определенное определение конструктора. Давайте посмотрим на это на примере.
class Employee: def __init__(self, id): self.employee_id = id # this will overwrite earlier defined constructor def __init__(self, id, n): self.employee_id = id self.emp_name = n def work(self): print(f'{self.emp_name} is working') emp = Employee(100, 'Pankaj') emp.work() emp = Employee(100) # will raise Error emp.work()
Вывод:
Pankaj is working Traceback (most recent call last): File "/Users/pankaj/Documents/PycharmProjects/AskPython/hello-world/class_examples.py", line 19, in <module> emp = Employee(100) TypeError: __init__() missing 1 required positional argument: 'n'