Чем метод отличается от функции в Python?

В отличие от функции, метод узко специализирован и может быть применен только к объектам, которые его поддерживают. Например, метод списков append() может быть применен только к ним. Применение данного метода к другим объектам, которые его не поддерживают (строки или кортежи) вызовет ошибку. Но есть и такие методы, которые хорошо работают с несколькими типами объектов, например метод count() может применяться к строкам, спискам или кортежам

Метод по сути это та же функция, но так как она определена внутри класса, и первым её аргументом является self , то она становится связанным методом bound method , получившим доступ к атрибутам связанного объекта (экземпляра класса).
01. function VS method:
![]()
A function is a block of code which perform specific task and can be used as many times as need without writing the same code again. So, the main purpose of function is “code reusability”.
function should have a unique name. According to PEP-8 Function names should be lowercase, with words separated by underscores as necessary to improve readability. function parameter receive and assign them with arguments value.
function body contain specific task.
Functions are two types :
- pre-define functions
- user-define Function
Functions can be used inside the class as well as outside of the class.
method :
A method in python is similar to a function, except it is associated with object/classes.
Use the function naming rules for method: lowercase with words separated by underscores as necessary to improve readability.
method is user defined only.
Methods are always used the Object Oriented Programming Language.
And always defined within a class.
02. arguments VS parameters
They are almost same but the main difference between them is that the parameter is declare when function is created, while arguments is passed when calling the function.
Here, a and b are parameters and and the arguments being passed through are 3 and 4.
In python parameters don’t need to specify its data type. Thus, we should control what exact type is passed through as an argument to the function.
03. iterable VS iterator :
An iterable is a object which has a __iter__() method. It can possibly iterated over several times, such as list() s and tuple() s.
An iterator is the object which iterates. It is returned by an __iter__() method, returns itself via its own __iter__() method and has a next() method ( __next__() in 3.x).
04. map VS filter :
The map() function executes a specified function for each item in a iterable. The basic function of map() is to manipulate iterables. Each item is sent to the function as a parameter.
iterable : You can send as many iterables as you like, just make sure the function has one parameter for each iterable.
map iterate over the iterables. Only takes one argument from each iterable. So, Number of function parameter must be equal to number of iterables.
map takes all items one by one from iterable and apply function over each item. Number of output in case of map is same as number of item in each iterable.
filter :
As the name suggests, it is used to filter the iterables as per the conditions.
The filter() function returns an iterator were the items are filtered through a function to test if the item is accepted or not.
filter takes all items one by one from iterable and apply function over each item to check whether it is True or not. If True then that particualr item is seen. Number of output in case of filter is equal to the number of item output as True.
In the above code, filter_1 output is same as input iterable ‘nums’. ‘num * num’ multiplication has not apply on iterable.
So, map takes all items in a iterable and permits you to apply a function to it though Filter takes all items in a iterable and runs that through a function to make another iterable with all items that output as True without any change to item.
13. Методы¶
Не так просто дать определение, что же такое объектно-ориентированное программирование, но мы уже видели некоторые его свойства:
- Программы строятся из определений объектов и определений функций, и большинство вычислений выражается в терминах операций над объектами.
- Каждое определение объекта соответствует некоторому объекту или понятию реального мира, а функции, работающие с объектом, соответствуют тому, как взаимодействуют реальные объекты.
Например, класс Time , определенный в предыдущей главе, соответствует тому, как люди привыкли записывать время. А определенные нами функции соответствуют действиям, которые люди выполняют над временем. Подобным же образом, классы Point и Rectangle соответствуют математическим понятиям точки и прямоугольника.
До сих пор мы не пользовались средствами, которые Python предоставляет для объектно-ориентированного программирования. Строго говоря, эти средства не являются необходимыми для создания программ. По большей части, они предоставляют альтернативный синтаксис для тех вещей, которые мы уже делали. Однако, часто этот синтаксис оказывается более кратким и выразительным.
Например, в программе Time нет очевидной связи между определением класса и следующими за ним определениями функций. Если присмотреться, то оказывается, что каждая из функций принимает в качестве параметра, по крайней мере, один объект Time .
Это наблюдение мотивирует нас перейти к методам. Мы уже встречали некоторые методы, например, keys и values , которые вызываются на словарных объектах. Каждый метод связан с классом и предназначен для использования с объектами этого класса.
Методы похожи на функции, но есть два отличия:
- Методы определяются внутри определения класса, чтобы сделать отношения между классом и методом явными.
- Синтаксис для вызова метода отличается от синтаксиса для вызова функции.
В следующих разделах мы превратим функции из предыдущей главы в методы. Это преобразование почти механическое. Мы сделаем это, выполнив определенную последовательность шагов.
13.2. Метод increment ¶
Для начала давайте превратим в метод функцию increment .
Для этого достаточно поместить определение функции внутрь определения класса. Хорошим тоном будет также переименование параметра time в self (хоть делать это и не обязательно). Как вы, должно быть, помните, в сообществе программистов Python существует соглашение, согласно которому первому параметру метода дают имя self (англ.: сам).
Обратите внимание на сдвиг кода метода относительно заголовка класса:
Преобразование чисто механическое — мы переместили определение метода в определение класса, и изменили имя первого параметра.
Теперь можно вызвать increment как метод, используя точечную нотацию:
Объект, на котором вызывается метод, присваивается первому параметру метода. Таким образом, в данном случае my_time присваивается параметру self . Второй параметр, seconds , получает значение 600 .
В процедурном программировании предполагается, что функции выполняют необходимые действия. Синтаксис для вызова функции , increment(my_time, 600) , говорит: Эй, increment ! Вот тебе объект Time и 600 секунд, сделай с ними все необходимое.
Синтаксис объектно-ориентированном программировании предполагает, что необходимые действия выполняет объект. Вызов, подобный my_time.increment(600) говорит: Эй, my_time ! Пожалуйста, увеличь себя на 600 секунд!
Является ли полезным такое изменение взгляда на вещи? Дело в том, что иногда, передавая ответственность от функций объектам, мы можем писать более гибкий код. Также становится проще поддерживать и повторно использовать такой код.
13.3. Более сложный пример¶
Функция after немного более сложная, поскольку она имеет дело с двумя объектами Time . Первый из параметров переименуем в self , второй оставим без изменений:
Мы вызываем этот метод на одном объекте Time , и передаем второй объект Time в качестве аргумента:
Программа состоит из предложений на почти естественном английском языке: Если время готовности (done_time) позднее, чем текущее время (current_time), то.
13.4. Инициализирующий метод¶
Как мы уже знаем, инициализирующий метод — это специальный метод, который вызывается при создании объекта. Этот метод имеет имя __init__ (два символа подчеркивания, init , и еще два символа подчеркивания). Инициализирующий метод класса Time выглядит так:
Заметьте, что между атрибутом self.hours и параметром hours не возникает конфликта имен. Точечная нотация устраняет конфликт.
Метод, вызываемый при создании объекта и инициализирующий состояние объекта, также называют конструктором. В Python метод __init__ является конструктором.
Когда мы создаем объект Time , указанные нами аргументы передаются конструктору:
Поскольку параметры метода __init__ имеют значения по умолчанию, мы можем и не передавать аргументы при создании объекта:
Или передать только первый аргумент:
Или только первые два аргумента:
Мы также можем передать часть аргументов, явно поименовав их:
13.5. Метод __str__ ¶
Метод __str__ имеет специальное назначение в Python, он возвращает строковое представление объекта. Определим метод __str__ для класса Time , позаимствовав решение из функции print_time из предыдущей главы:
Если класс предоставляет метод с именем __str__ , то тем самым переопределяет поведение встроенной функции Python str .
При выводе объекта Time с помощью print неявно вызывается __str__ на этом объекте. Поэтому добавление метода __str__ также меняет поведение print :
Как видите, добавление метода __str__ к классу Time сделало ненужным написанную ранее функцию print_time .
Когда мы пишем новый класс, мы почти всегда начинаем с написания метода __init__ , который облегчает создание объектов, и метода __str__ , который часто полезен для отладки.
13.6. Снова Points ¶
Теперь, для закрепления изученного материала, давайте перепишем класс Point в стиле ООП:
Инициализирующий метод принимает x и y как опциональные параметры, значение по умолчанию для каждого из них 0.
Метод __str__ возвращает строковое представление объекта Point :
13.7. Перегрузка операторов¶
Некоторые языки программирования позволяют изменять определения встроенных операторов для использования этих операторов с типами, определенными пользователем. Это свойство называется перегрузкой операторов.
Например, для перегрузки оператора + , класс должен предоставить метод __add__ :
Как обычно, первый параметр метода представляет объект, на котором вызывается метод. Второй параметр удачно назван other (англ.: другой) чтобы противопоставить его первому, self . Для того, чтобы сложить два объекта Point , мы создаем и возвращаем новый объект Point , содержащий сумму координат x и сумму координат y двух объектов.
Теперь, когда мы применяем оператор + к объектам Point , Python вызывает метод __add__ :
Выражение p1 + p2 равнозначно выражению p1.__add__(p2) , только более изящно.
В качестве упражнения вам будет предложено самостоятельно написать метод __sub__(self, other) , который перегрузит оператор вычитания.
Перегрузить оператор умножения можно, определив метод __mul__ , или __rmul__ , или оба эти метода. Если левый операнд оператора * является объектом Point , то Python вызовет метод __mul__ , который ожидает, что второй операнд также является объектом Point . Этот метод рассчитает произведение точек согласно известной из математики формуле (сумма квадратов катетов равна квадрату гипотенузы):
Если левый операнд оператора * является примитивным числовым типом, а правый операнд — объект Point , то Python вызовет метод __rmul__ , который выполнит умножение объекта Point на число:
Результатом будет новый объект Point , чьи координаты кратны первоначальным координатам. Если other окажется типом, который нельзя умножить на число с плавающей точкой, то __rmul__ сгенерирует ошибку.
Следующий пример демонстрирует оба вида умножения:
А что случится, если мы попробуем вычислить p2 * 2 ? Так как первый аргумент является объектом Point , то Python вызовет __mul__ и передаст 2 в качестве второго аргумента. Внутри метода, __mul__ попытается получить атрибут x объекта other , что закончится неудачей, поскольку целое число не имеет атрибутов:
13.8. Полиморфизм¶
Большинство написанных нами методов работают только с определенными типами данных. Когда создается новый класс, то пишутся методы, которые работают с объектами этого класса.
Но есть некоторые операции, которые хотелось бы уметь выполнять с разными типами данных, например, арифметические операции из предыдущего раздела. Если разные типы поддерживают одни и те же операции, значит, можно писать функции, работающие с любым из этих типов.
Например, операция multadd (обычная в линейной алгебре) имеет три параметра; первые два перемножаются, и к полученному произведению прибавляется третий. Можем записать это на языке Python таким образом:
Этот метод будет работать с любыми значениями x и y , которые можно перемножить, и с любым значением z , которое можно прибавить к полученному произведению.
Можно вызвать этот метод с числовыми значениями:
Или с объектами Point :
В первом случае, Point умножается на число и складывается с другим Point . Во втором случае, произведение двух Point дает числовое значение, и третий аргумент также является числом.
Функции, подобные этой, которые могут принимать аргументы различных типов, называются полиморфными.
В качестве еще одного примера, рассмотрим метод front_and_back , который печатает список дважды, сначала — в прямом, а затем и в обратном порядке:
Поскольку метод reverse модифицирующий, мы делаем копию списка, прежде чем расставить его элементы в обратном порядке. Таким образом, метод reverse не изменяет список, который он получает в качестве параметра.
Вот пример использования метода front_and_back со списком:
Поскольку мы предназначили эту функцию для работы со списками, неудивительно, что она работает, как ожидалось. Было бы удивительно, если бы мы смогли применить эту функцию к объекту Point .
Для того, чтобы определить, может ли функция быть применена к новому типу, мы воспользуемся основным правилом полиморфизма: Если все операции внутри функции могут быть применены к данному типу, то вся функция может быть применена к данному типу.
Операции внутри функции включают copy , reverse и print .
copy работает с любым объектом. Мы уже написали метод __str__ для Point . Нам остается написать метод reverse для класса Point :
Теперь можно передать объект Point функции front_and_back :
Замечательное свойство языка Python — это непреднамеренный полиморфизм, когда вы обнаруживаете, что написанная вами функция может работать с типами, для которых вы ее не предназначали.
13.9. Глоссарий¶
13.10. Упражнения¶
Переделайте функцию convert_to_seconds в метод класса Time :
Добавьте в класс Point метод __sub__(self, other) , который перегрузит оператор вычитания, и попробуйте с ним поработать.
Перепишите класс Rectangle в объектно-ориентированном стиле, определив методы __init__ и __str__ .
Добавьте в класс Rectangle методы move_rect и grow_rect , созданные на основе одноименных функций из предыдущей главы.
Определите класс Pet (англ.: любимое животное) с атрибутами имя и возраст, инициализируемыми в методе __init__ значениями параметров метода. Метод __str__ должен возвращать строку с именем и возрастом животного. Поэкспериментируйте, создавая объекты класса Pet и выводя их на печать.
Функции и методы в Python: передача функции в функцию. Декоратор
Эта статья посвящена теме декораторов в Python. Поговорим о том, что это такое, уделим особое внимание свойствам функций в Python, на базе которых реализована данная идея, а также рассмотрим декораторы, которые принимают аргументы и возвращают значение из функции.
Что надо знать о методах и функциях в Python?
Говоря о функциях в Python, нужно упомянуть два аспекта: 1) функция в Python — есть объект специального вида, который можно передавать в виде аргумента другим функциям; 2) внутри функций в Python вы можете создавать другие функции, а также вызывать их, возвращая результат посредством return.
Теперь давайте поговорим об этом подробнее.
Функция как объект в Python
В языке программирования Python часто практикуется передача одной функции в виде аргумента другой функции. Представьте, что есть список целых чисел, и вы желаете на его базе получить другой список с элементами, которые будут квадратами первого списка. Вот, как это можно реализовать в Python:
В нашем примере мы передали функции map в виде первого аргумента функцию sq. Последняя будет по очереди применяться ко всем элементам нашего списка a.
Кроме того, в Python функция является специальным объектом, имеющим метод __call__() . Представьте, что мы создали следующий класс:
Объект такого класса в Python мы сможем вызывать как функцию:
Функция внутри функции в Python
Функции в Python мы можем создавать, вызывать и возвращать из других функций. Кстати, на этом основана идея замыкания (closures) в Python.
Давайте создадим функцию, умножающую 2 числа:
В этой функции в Python реализованы два важных свойства: 1) внутри функции mul() мы создаём ещё одну функцию helper() ; 2) функция mul() возвращает нам функцию helper() в качестве результата работы.
Вызов этой функции в Python:
Особенность заключается в том, что мы можем создавать на базе функции mul() собственные кастомизированные функции. Давайте создадим функцию в Python, умножающую на 3:
В результате была построена функция three_mul() , умножающая на 3 любое переданное ей число.
Декоратор функции в Python
Конструктивно речь идёт о некоторой функции, в качестве аргумента которого выступает другая функция. Декоратор в Python добавляет дополнительный функционал к функции, не меняя её содержимое.
Создание
Представьте, что мы имеем пару простых функций в Python:
При этом мы желаем их дополнить таким образом, чтобы перед вызовом основного кода нашей функции печаталась строчка “Start function”, а в конце – строка “Stop function”.
Реализовать поставленную задачу можно несколькими методами. Во-первых, мы можем добавить необходимые строки в конец и начало каждой функции. Но вряд ли это удобно, ведь если мы пожелаем их убрать, придётся модифицировать тело функции.
Теперь поговорим о втором пути. Для начала создадим функцию:
Теперь нужно обернуть функции в оболочку:
Обратите внимание, что функции first_test и second_test не поменялись.
Наши функции second_test_wrapped и first_test_wrapped обладают функционалом, который нам и нужен.
Теперь, если надо, чтобы так работали функции с именами first_test и second_test, делаем следующее:
Выполненные нами действия и являются реализацией идеи декоратора.
Правда, вместо строк:
мы можем написать иначе:
В нашем случае @simple_decore – это не что иное, как декоратор функции.
Передаём аргументы в функцию с помощью декоратора
Бывает, что функция требует наличие аргумента, поэтому мы можем передать его через декоратор. Давайте создадим декоратор, принимающий аргумент и выводящий информацию о декорируемой нами функции и её аргументе.
Чтобы продемонстрировать работу, создадим функцию, выводящую квадратный корень переданного ей числа, а в качестве декоратора, укажем созданный param_transfer:
Теперь давайте выполним данную функцию с аргументом 4:
Декораторы для методов класса в Python
С декоратором можно объявлять и методы классов. Давайте выполним модификацию декоратора param_transfer:
Теперь приступим к созданию класса для представления 2-мерного вектора (математического). В классе определим метод norm() , выводящий модуль вектора.
Что же, осталось продемонстрировать работу нашего метода:
Возвращаем результат работы функции через декоратор
Зачастую создаваемые функции выполняют возвращение какого-либо значения. Чтобы это стало возможным осуществить через декоратор, нужно специальным образом построить нашу внутреннюю функцию:
Возможно применение этого декоратора и для оборачивания функций, принимающих различные аргументы и возвращающие значение: