Пять важных понятий, необходимых для быстрого старта в python ооп
Содержание:
- Введение в ООП в Python
- Changes to raise
- Исследовательский анализ данных
- Функция __init__()
- Методы
- Типы внутренних классов
- Полиморфизм
- Создание объекта
- Уничтожение объектов (Сборка мусора)
- Использование метакласса в Python
- Давайте попрактикуемся
- Доступ к атрибутам
- Классы Python 3: работа с более чем одним объектом
- Операторы перегрузки
- Классы в Python
- Операции со строками
- Variable Annotations
- Creating an Object in Python
- Overloading Operators
- Полиморфизм в Python
Введение в ООП в Python
Python — это мультипарадигмальный язык. Это означает, что он поддерживает различные подходы к программированию.
Одной из наиболее популярных парадигм является создание объектов. Она известна как объектно-ориентированное программирование (ООП).
Объект имеет две характеристики:
- атрибуты;
- поведение;
Рассмотрим на примере:
Объект – это попугай:
- имя, возраст, цвет являются атрибутами;
- пение, танцы — это поведение;
Концепция ООП в Python направлена на создание кода для многократного использования. Эта концепция также известна как DRY (Don’t Repeat Yourself).
В Python концепция ООП реализует несколько принципов:
Наследование | Использование элементов из нового класса без изменения существующего класса. |
Инкапсуляция | Скрытие приватных элементов класса от других объектов. |
Полиморфизм | Концепция использования объекта с одинаковым интерфейсом без получения информации о его типе и внутренней структуре. |
Changes to raise
The statement has been extended to allow raising a class
exception without explicit instantiation. The following forms, called
the «compatibility forms» of the statement, are allowed:
- exception
- exception, argument
- exception, (argument, argument, …)
When exception is a class, these are equivalent to the
following forms:
- exception()
- exception(argument)
- exception(argument, argument, …)
Note that these are all examples of the form
raise instance
which in itself is a shorthand for
raise class, instance
where class is the class to which instance belongs.
In Python 1.4, only the forms
- class, instance and
- instance
were allowed;
in Python 1.5 (starting with 1.5a1) the forms
- class and
- class, argument(s)
were added. The allowable forms for string exceptions are unchanged.
For various reasons, passing None as the second argument to
raise is equivalent to omitting it. In particular, the
statement
raise class, None
is equivalent to
raise class()
and not to
raise class(None)
Likewise, the statement
raise class, value
where
value happens to be a tuple is equivalent to passing the
tuple’s items as individual arguments to the class constructor, rather
than passing value as a single argument (and an empty tuple
calls the constructor without arguments). This makes a difference
because there’s a difference between and
.
These are all compromises — they work well with the kind of
arguments that the standard exceptions typically take (like a simple
string). For clarity in new code, the form
raise class(argument, …)
is recommended (i.e. make an explicit call to the constructor).
How Does This Help?
The motivation for introducing the compatibility forms was to allow
backward compatibility with old code that raised a standard exception.
For example, a __getattr__ hook might invoke the statement
raise AttributeError, attrname
when the desired attribute is not defined.
Using the new class exceptions, the proper exception to raise would
be (attrname); the compatibility
forms ensure that the old code doesn’t break. (In fact, new code that
wants to be compatible with the -X option must use the
compatibility forms, but this is highly discouraged.)
Исследовательский анализ данных
набор данныхмы будем использовать содержит 8124 экземпляров грибов с 22 функциями. Среди них мы находим форму крышки гриба, цвет крышки, цвет жабры, тип вуали и т. Д. Конечно, это также говорит нам, является ли гриб съедобным или ядовитым.
Давайте импортируем некоторые библиотеки, которые помогут нам импортировать данные и манипулировать ими. В вашей записной книжке запустите следующий код:
Общий первый шаг для проекта науки о данных состоит в том, чтобы выполнитьисследовательский анализ данных(ЭДА). Этот шаг обычно включает в себя изучение дополнительных данных, с которыми вы работаете. Возможно, вы захотите узнатьформавашего набора данных (сколько строк и столбцов), количество пустых значений и визуализировать части данных, чтобы лучше понять взаимосвязь между функциями и целью.
Импортируйте данные и увидите первые пять столбцов со следующим кодом:
Всегда хорошо иметь набор данных вданныепапка в каталоге проекта. Кроме того, мы сохраняем путь к файлу в переменной, так что, если путь когда-либо изменяется, нам нужно только изменить присвоение переменной.
После запуска этой ячейки кода вы должны увидеть первые пять строк. Вы замечаете, что каждая функция является категориальной, и для определения определенного значения используется буква. Конечно, классификатор не может принимать буквы в качестве входных данных, поэтому нам придется изменить это в конце концов.
Пока давайте посмотрим, если наш набор данныхнесбалансированный.Несбалансированный набор данных — это когдаодин класс гораздо больше, чем другой, В идеале, в контексте классификации, мы хотим равное количество экземпляров каждого класса. В противном случае нам нужно будет реализовать расширенные методы выборки, такие какпередискретизация меньшинства.
В нашем случае мы хотим посмотреть, есть ли в наборе данных равное количество ядовитых и съедобных грибов. Мы можем построить частоту каждого класса следующим образом:
И вы получите следующий график:
Подсчет каждого класса
Потрясающе! Это похоже на довольно сбалансированный набор данных с почти равным количеством ядовитых и съедобных грибов.
Теперь я хотел посмотреть, как каждая функция влияет на цель. Для этого я сделал гистограмму всех возможных значений, разделенных классом грибов. Делать это вручную для всех 22 функций не имеет смысла, поэтому мы создаем эту вспомогательную функцию:
оттенокдаст цветовой код ядовитому и съедобному классу.данныеПараметр будет содержать все функции, кроме класса гриба. Выполнение кода ячейки ниже:
Вы должны получить список из 22 участков. Вот пример вывода:
Поверхность крышки
Потратьте некоторое время на просмотр всех графиков.
Теперь посмотрим, есть ли у нас пропущенные значения. Запустите этот кусок кода:
И вы должны увидеть каждый столбец с количеством пропущенных значений. К счастью, у нас есть набор данных без пропущенных значений. Это очень редко, но мы не будем жаловаться.
Функция __init__()
У всех классов есть функция . Её можно менять в любое время. Функция выполняется всякий раз, когда из класса создаётся объект. Она может использоваться для инициализации переменных класса. становится очень полезной, когда нам нужно, чтобы класс Python всегда начинался с тех или иных свойств.
В качестве примера возьмём следующий код:
class Person: def __init__(self, name, gender): self.name = name self.gender = gender self.country = "USA"person_1 = Person("Bob", "Male")person_2 = Person("Kate", "Female")print(person_1.name)print(person_1.gender)print(person_1.country)print(person_2.name)print(person_2.gender)print(person_2.country)
Здесь у нас есть два человека с классом Person и именами Bob и Kate (типа мы их создали). В обоих классах исполнялась функция , инициализируя переменные класса для имени, пола и страны человека.
Что касается имени и пола, мы передали классу свои переменные, которые требовались в . Переменная «страна» инициализировалась при создании объекта в этой же функции, но с одним отличием: по причине того, что она не является переменной функции , значение не может быть задано извне. Поэтому у всех будет одна страна — США.
Результат этого кода будет такой:
BobMaleUSAKateFemaleUSA
Методы
Методы — это функции, определенные внутри класса. Они используются для определения поведения объекта.
Пример 2: Создание методов в Python
class Parrot: # атрибуты экземпляра def __init__(self, name, age): self.name = name self.age = age # метод экземпляра def sing(self, song): return "{} sings {}".format(self.name, song) def dance(self): return "{} is now dancing".format(self.name) # создаем экземпляр объекта blu = Parrot("Blu", 10) # вызываем методы экземпляра print(blu.sing("'Happy'")) print(blu.dance())
Результат работы программы:
Blu sings 'Happy' Blu is now dancing
В приведенном выше примере мы определяем два метода sing() и dance(). Их называют методами экземпляра, так как они вызываются для экземпляра объекта, то есть для blu.
Типы внутренних классов
Внутренний класс можно далее разделить на части, которые мы рассмотрим далее в деталях.
1. Несколько Внутренних Классов
class Employe: def __init__(self): .intern() .head() def show(self): print('Employe List') print('Name:', self.name) class intern: def __init__(self): def display(self): print("Name:", self.name) print("Id:", self.Id) class head: def __init__(self): def display(self): print("Name:", self.name) print("Degree:", self.Id) () outer.show() .intern.head print() d1.display() print() d2.display()
Выход:
Employe List Name: Facebook Name: Smith Id: 657 Name: Auba Degree: 007
Класс, имеющий внутри себя более одного внутреннего класса, называется множественным внутренним классом. Выше мы его успешно реализовали. Здесь класс Сотрудников-это наш внешний класс. Внутри которого мы создали 2 подкласса. Один из них носит имя Стажера, а другой-имя руководителя.
2. Многоуровневый внутренний класс
class multi: def __init__(self): .Inner() .inner.InnerInner() def show(self): print("This is Outer class") ## inner class class Inner: def __init__(self): .InnerInner() def show_classes(self): print("This is Inner class") print(self.innerinner) class InnerInner: def inner_display(self, msg): print("InnerInner class") print(msg) def inner_display(self, msg): print("This is Inner class") print(msg) () outer.show().Inner() .InnerInner() innerinner.inner_display("completed")
Выход:
This is Outer class InnerInner class completed
Многоуровневый класс можно понимать как класс, имеющий внутренний класс. Кроме того, у внутреннего класса есть внутренний класс. Из кода вы можете получить представление о том, как выполнить этот конкретный процесс. Оба типа просты в исполнении и понимании. Вы можете использовать их в соответствии с вашими потребностями.
Полиморфизм
Полиморфизм — это способность использовать в ООП общий интерфейс для нескольких форм (типов данных).
Предположим, что нужно раскрасить фигуру. Есть несколько вариантов фигуры (прямоугольник, квадрат, круг). Мы могли бы использовать тот же метод, чтобы закрасить любую форму. Эта концепция называется полиморфизмом.
Пример 5: Использование полиморфизма в Python
class Parrot: def fly(self): print("Parrot can fly") def swim(self): print("Parrot can't swim") class Penguin: def fly(self): print("Penguin can't fly") def swim(self): print("Penguin can swim") # общий интерфейс def flying_test(bird): bird.fly() #создаем объекты blu = Parrot() peggy = Penguin() # передаем объекты flying_test(blu) flying_test(peggy)
Результат:
Parrot can fly Penguin can't fly
Мы определили два класса: Parrot и Penguin . У каждого из них есть общий метод fly(), но они разные.
Чтобы реализовать полиморфизм, мы создали общий интерфейс. То есть, функцию flying_test(), которая может принимать любой объект. Затем мы передали объекты blu и peggy в функцию flying_test().
Создание объекта
Мы увидели, что объект класса можно использовать для доступа к различным атрибутам.
Его также можно использовать для создания новых экземпляров объекта (создания экземпляров) этого класса. Процедура создания объекта аналогична вызову функции.
>>> harry = Person()
Это создаст новый экземпляр объекта с именем harry. Мы можем получить доступ к атрибутам объектов, используя префикс имени объекта.
Атрибуты могут быть данными или методом. Методы объекта ‒ это соответствующие функции этого класса.
Это означает, что поскольку Person.greet является объектом функции (атрибутом класса), Person.greet будет объектом метода.
class Person: "This is a person class" age = 10 def greet(self): print('Hello') # create a new object of Person class harry = Person() # Output: <function Person.greet> print(Person.greet) # Output: <bound method Person.greet of <__main__.Person object>> print(harry.greet) # Calling object's greet() method # Output: Hello harry.greet()
Выход
<function Person.greet at 0x7fd288e4e160> <bound method Person.greet of <__main__.Person object at 0x7fd288e9fa30>> Hello
Вы могли заметить параметр self в определении функции внутри класса, но мы вызвали этот метод просто как harry.greet() без каких-либо аргументов. Это все еще работало.
Это потому, что всякий раз, когда объект вызывает свой метод, сам объект передается в качестве первого аргумента. Итак, harry.greet() переводится как Person.greet (harry).
В общем случае вызов метода со списком из n аргументов эквивалентен вызову соответствующей функции со списком аргументов, который создается путем вставки объекта метода перед первым аргументом.
По этим причинам первым аргументом функции в классе должен быть сам объект. Это условно называется self. Его можно назвать иначе, но мы настоятельно рекомендуем следовать правилам.
Теперь вы ознакомились с объектом класса, объектом экземпляра, объектом функции, объектом метода и их различиями.
Уничтожение объектов (Сборка мусора)
Python автоматически удаляет ненужные объекты (встроенные типы или экземпляры классов), чтобы освободить пространство памяти. Процесс, посредством которого Python периодически восстанавливает блоки памяти, которые больше не используются, называется сборкой мусора.
Сборщик мусора в Python запускается во время выполнения программы и запускается, когда счетчик ссылок на объект достигает нуля. Количество ссылок объекта изменяется по мере изменения количества псевдонимов, которые на него указывают.
Счетчик ссылок на объект увеличивается, когда ему присваивается новое имя или он помещается в контейнер (список, кортеж или словарь). Счетчик ссылок объекта уменьшается, когда он удаляется с помощью del , его ссылка переназначается или его ссылка выходит за пределы области видимости. Когда счетчик ссылок объекта достигает нуля, Python собирает его автоматически.
a = 40 # Create object <40> b = a # Increase ref. count of <40> c = # Increase ref. count of <40> del a # Decrease ref. count of <40> b = 100 # Decrease ref. count of <40> c = -1 # Decrease ref. count of <40>
Обычно вы не замечаете, когда сборщик мусора уничтожает потерянный экземпляр и освобождает его пространство. Но класс может реализовать специальный метод __del __ () , называемый деструктором, который вызывается, когда экземпляр собирается быть уничтоженным. Этот метод может использоваться для очистки любых ресурсов памяти, используемых экземпляром.
Пример
Этот деструктор __del __ () печатает имя класса экземпляра, который должен быть уничтожен
#!/usr/bin/python class Point: def __init__( self, x=0, y=0): self.x = x self.y = y def __del__(self): class_name = self.__class__.__name__ print class_name, "destroyed" pt1 = Point() pt2 = pt1 pt3 = pt1 print id(pt1), id(pt2), id(pt3) # prints the ids of the obejcts del pt1 del pt2 del pt3
Когда приведенный выше код выполняется, он дает следующий результат
3083401324 3083401324 3083401324 Point destroyed
Примечание. В идеале вы должны определять свои классы в отдельном файле, а затем импортировать их в основной файл программы с помощью оператора import .
Использование метакласса в Python
Причина использования метаклассов заключается в том, что классы Python сами являются объектами. Поскольку классы являются объектами, мы можем выполнять с ними различные операции, такие как присвоение их переменной, копирование и т. Д.
А поскольку они являются объектами, мы можем создавать их динамически, как и любой другой объект.
Чтобы лучше понять концепцию метаклассов, мы сначала посмотрим, как Python определяет классы. Язык определяет все как объект, будь то , или что-то еще.
Если вы помните, чтобы посмотреть на тип любого объекта Python, мы используем функцию .
>>> print(type(123)) <class 'int'> >>> print(type()) <class 'list'> >>> class A(): ... def __init__(self): ... pass ... >>> a = A() >>> print(type(a)) <class '__main__.A'>
Как мы видим, он возвращает для каждого случая. Но чтобы увидеть, как Python определяет сам класс, мы просто посмотрим на его тип.
>>> print(type(type(123)) <class 'type'> >>> print(type(A)) <class 'type'>
Как видите, тип ( ) — это класса! Получается, что класс определяется самим классом? Что это за явление?
Это концепция метакласса, который служит для определения других классов. По сути, это фабрика классов, из которой могут быть определены другие классы, такие как s и s.
— это метакласс, который язык использует для создания объекта. (поэтому у каждого объекта есть тип)
А поскольку — это метакласс, мы можем создавать из него другие классы.
Давайте попрактикуемся
- obj.method()
- obj.atr
- надо определить класс
- создать объект
- обратиться к каждому из атрибутов, записав туда кастомные данные
- обратиться к каждому объекту, передав туда кастомные аргументы
на самом деле инициализатора, но мы в этой статье не будем углубляться в разницуВажно:
- метод __init__(), как и другие методы класса должен принимать как минимум 1 аргумент self
- к аргументам объекта можно обращаться из метода как аргументам self (например, self.arg)
- Если аргумент создаётся конструктором __init__, то его не нужно описывать в классе как отдельную переменную
Давайте создадим чуть более осмысленный класс.Интересный эффект, который можно заметить — после пересоздания класса ранее созданные объекты не меняют своего поведения.
Геттеры и Сеттеры
- сеттер — setColor — проверяет, что передаётся строка и записывает её в атрибут color экземпляра. Если передан другой тип данных, возвращает ошибку.
- геттер — getColor — возвращает значение атрибута color текущего экземпляра
Наследование
- атрибуты: число ног, имя, возраст.
- методы: геттеры и сеттеры
- атрибуты: имя и т.п.
- методы: «говорение» (мяу) и т.п.
Такие классы ещё иногда называются «примесью», дальше станет понятно почему.Удивительно, но это работает.
- наследник получает все методы и атрибуты обоих родителей.
- если у нескольких родителей есть одноимённые методы, то автоматически наследник получит методы того, кто раньше в списке (в нашем случае раньше был гео маркер, поэтому конструктор был унаследован от него, а не от организации).
Наследование от нескольких родителей иногда считается сомнительной практикой, будьте с ним аккуратны.
Переменные класса
- в атрибуте ID каждого объекта хранится его уникальный порядковый номер
- в переменной tag класса хранится число созданных объектов (тут надо быть осторожнее, так как возможно мы захотим уменьшать это число при удалении объекта).
Доступ к атрибутам
Вы получаете доступ к атрибутам объекта, используя оператор точки с объектом. Переменная класса будет доступна с использованием имени класса следующим образом:
emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
Теперь, объединяя все концепции
#!/usr/bin/python class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary "This would create first object of Employee class" emp1 = Employee("Zara", 2000) "This would create second object of Employee class" emp2 = Employee("Manni", 5000) emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
Когда приведенный выше код выполняется, он дает следующий результат
Name : Zara ,Salary: 2000 Name : Manni ,Salary: 5000 Total Employee 2
Вы можете добавлять, удалять или изменять атрибуты классов и объектов в любое время
emp1.age = 7 # Add an 'age' attribute. emp1.age = 8 # Modify 'age' attribute. del emp1.age # Delete 'age' attribute.
Вместо использования обычных операторов для доступа к атрибутам, вы можете использовать следующие функции:
- GetAttr (объект, имя ) — для доступа к атрибуту объекта.
- Hasattr (объект, имя) — проверить , если атрибут существует или нет.
- SetAttr (объект, имя, значение) — установить атрибут. Если атрибут не существует, он будет создан.
- Delattr (объект, имя) — для удаления атрибута.
hasattr(emp1, 'age') # Returns true if 'age' attribute exists getattr(emp1, 'age') # Returns value of 'age' attribute setattr(emp1, 'age', 8) # Set attribute 'age' at 8 delattr(empl, 'age') # Delete attribute 'age'
Классы Python 3: работа с более чем одним объектом
Классы позволяют создавать много похожих объектов на основе одного образца. Чтобы понять, как это работает, добавим еще один объект Shark в нашу программу:
shark.py
classShark: def__init__(self, name): self.name = name defswim(self): print(self.name + " is swimming.") defbe_awesome(self): print(self.name + " is being awesome.") defmain(): sammy = Shark("Sammy") sammy.be_awesome() stevie = Shark("Stevie") stevie.swim() if __name__ == "__main__": main()
Мы создали второй объект Shark с именем stevie, и передали ему имя «Stevie». В этом примере используются методы be_awesome() с sammy и метод swim() со stevie.
Запустим программу:
python shark.py Вывод Sammy is being awesome. Stevie is swimming.
Результат показывает, что мы используем два разных объекта: объект sammy и объект stevie. Они оба относятся к классу Shark.
Классы позволяют создавать более одного объекта по одному и тому же шаблону, не создавая каждый из них с нуля.
Операторы перегрузки
Предположим, что вы создали класс Vector для представления двумерных векторов. Что произойдет, когда вы добавите оператор «плюс»? Скорее всего, Python будет кричать на вас.
Однако вы можете определить метод __add__ в вашем классе для выполнения сложения векторов, и тогда оператор плюс будет вести себя так, как ожидалось:
пример
#!/usr/bin/python class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2,10) v2 = Vector(5,-2) print v1 + v2
Когда приведенный выше код выполняется, он дает следующий результат
Vector(7,8)
Классы в Python
Классы похожи на образец или прототип для создания объектов. Они определяются с помощью ключевого слова class.
Давайте определим класс Shark, который имеет две связанные с ним функции:
shark.py
classShark: defswim(self): print("The shark is swimming.") defbe_awesome(self): print("The shark is being awesome.")
Поскольку эти функции объявлены под классом Shark, они называются методами. Методы — это особый вид функции, который определен внутри класса.
Аргументом этих функций является слово self, которое является ссылкой на объекты, созданные на основе этого класса. Чтобы ссылаться на экземпляры (или объекты) класса, self всегда будет первым параметром.
Определение этого класса создает шаблон для объекта Shark, который мы сможем определить позже. То есть, если вы запустите программу, приведенную выше, ничего не будет возвращено.
Операции со строками
Строки в Python неизменяемые, вы не можете изменить один из символов строки. Любое изменение содержимого требует создания новой копии. Откройте интерпретатор и выполняйте перечисленные ниже примеры, для того чтобы лучше усвоить все написанное:
3. Объединение с преобразованием
Вы можете объединить строку с числом или логическим значением. Но для этого нужно использовать преобразование. Для этого существует функция str():
4. Поиск подстроки
Вы можете найти символ или подстроку с помощью метода find:
Этот метод выводит позицию первого вхождения подстроки losst.ru если она будет найдена, если ничего не найдено, то возвращается значение -1. Функция начинает поиск с первого символа, но вы можете начать с энного, например, 26:
В этом варианте функция вернет -1, поскольку строка не была найдена.
5. Получение подстроки
Мы получили позицию подстроки, которую ищем, а теперь как получить саму подстроку и то, что после нее? Для этого используйте такой синтаксис , просто укажите два числа или только первое:
Первая строка выведет подстроку от первого до второго символа, вторая — от второго и до конца
Обратите внимание, что отсчет начинается с нуля. Чтобы выполнять отсчет в обратном порядке, используйте отрицательное число
Вы можете заменить часть строки с помощью метода replace:
Если вхождений много, то можно заменить только первое:
7. Очистка строк
Вы можете удалить лишние пробелы с помощью функции strip:
Также можно удалить лишние пробелы только справа rstrip или только слева — lstrip.
Для изменения регистра символов существуют специальные функции:
9. Конвертирование строк
Есть несколько функций для конвертирования строки в различные числовые типы, это int(), float() , long() и другие. Функция int() преобразует в целое, а float() в число с плавающей точкой:
10. Длина строк
Вы можете использовать функции min(), max(), len() для расчета количества символов в строке:
Первая показывает минимальный размер символа, вторая — максимальный, а третья — общую длину строки.
11. Перебор строки
Вы можете получить доступ к каждому символу строки отдельно с помощью цикла for:
Для ограничения цикла мы использовали функцию len()
Обратите внимание на отступ. Программирование на python основывается на этом, здесь нет скобок для организации блоков, только отступы
Variable Annotations
PEP 526 introduced variable annotations. The style recommendations for them are
similar to those on function annotations described above:
-
Annotations for module level variables, class and instance variables,
and local variables should have a single space after the colon. -
There should be no space before the colon.
-
If an assignment has a right hand side, then the equality sign should have
exactly one space on both sides:# Correct: code: int class Point: coords: Tuple label: str = '<unknown>'
# Wrong: code:int # No space after colon code : int # Space before colon class Test: result: int=0 # No spaces around equality sign
-
Although the PEP 526 is accepted for Python 3.6, the variable annotation
syntax is the preferred syntax for stub files on all versions of Python
(see PEP 484 for details).
Footnotes
Hanging indentation is a type-setting style where all the lines in a paragraph are indented except the first line. In the context of Python, the term is used to describe a style where the opening parenthesis of a parenthesized statement is the last non-whitespace character of the line, with subsequent lines being indented until the closing parenthesis. |
Creating an Object in Python
We saw that the class object could be used to access different attributes.
It can also be used to create new object instances (instantiation) of that class. The procedure to create an object is similar to a function call.
This will create a new object instance named harry. We can access the attributes of objects using the object name prefix.
Attributes may be data or method. Methods of an object are corresponding functions of that class.
This means to say, since is a function object (attribute of class), will be a method object.
Output
<function Person.greet at 0x7fd288e4e160> <bound method Person.greet of <__main__.Person object at 0x7fd288e9fa30>> Hello
You may have noticed the parameter in function definition inside the class but we called the method simply as without any arguments. It still worked.
This is because, whenever an object calls its method, the object itself is passed as the first argument. So, translates into .
In general, calling a method with a list of n arguments is equivalent to calling the corresponding function with an argument list that is created by inserting the method’s object before the first argument.
For these reasons, the first argument of the function in class must be the object itself. This is conventionally called self. It can be named otherwise but we highly recommend to follow the convention.
Now you must be familiar with class object, instance object, function object, method object and their differences.
Overloading Operators
Suppose you have created a Vector class to represent two-dimensional vectors, what happens when you use the plus operator to add them? Most likely Python will yell at you.
You could, however, define the __add__ method in your class to perform vector addition and then the plus operator would behave as per expectation −
Example
#!/usr/bin/python class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2,10) v2 = Vector(5,-2) print v1 + v2
When the above code is executed, it produces the following result −
Vector(7,8)
Полиморфизм в Python
Это концепция, при которой функция может принимать несколько форм в зависимости от количества аргументов или типа аргументов, переданных функции.
В приведенном выше примере ключевое слово super используется для вызова метода родительского класса. Оба класса имеют метод show_salary. В зависимости от типа объекта, который выполняет вызов этой функции, выходные данные различаются.
Python также имеет встроенные функции, работающие с полиморфизмом. Одним из самых простых примеров является функция print в Python.
Вывод будет таким:
В приведенном выше фрагменте кода:
- Параметр конечного ключевого слова изменил работу функции print. Следовательно, «Привет!» не заканчивалось концом строки.
- len () в третьей строке возвращает int. Печать распознает тип данных и неявно преобразует его в строку и выводит его на консоль.