Python-сообщество
- Начало
- » Python для новичков
- » Python — разница между функцией и методом
#1 Май 3, 2014 10:17:24
setevoy От: Kiev, UA Зарегистрирован: 2013-02-22 Сообщения: 10 Репутация: 0 Профиль Отправить e-mail
Python — разница между функцией и методом

Сразу извиняюсь за столь нубский вопрос — просто до классов ещё не дошёл, а вопрос гложет
К примеру, для списков (list) есть и функции (пример — len(list)), и методы (пример — list.append(obj)) — в чём между ними разница?
> Help on built-in function len in module __builtin__: // т.е. он таки функция (модуля?);
> Help on method_descriptor in list: // т.е. это таки метод (класса?);
Именно между понятием и действиями — функции и метода?
#2 Май 3, 2014 10:20:00
FishHook От: Зарегистрирован: 2011-01-08 Сообщения: 8312 Репутация: 568 Профиль Отправить e-mail
Python — разница между функцией и методом
Методы — это функции, являющиеся атрибутами классов. Любой метод — функция, но не каждая функция — метод. Никакой принципиальной разницы между ними в питоне нет, это просто такая терминология.
Отредактировано FishHook (Май 3, 2014 10:23:02)
Что такое методы в Python
Ваня — ученик 4А класса. Ваня очень любит печеньки.
У строк есть методы (см. методы строк). Воспользуемся методом .replace() :
Код
print("Ваня — ученик 4А класса. Ваня очень любит печеньки.".replace("Ваня", "Игорь"))
Игорь — ученик 4А класса. Игорь очень любит печеньки.
В строке про Ваню его имя заменилось на “Игорь”.
Давайте разбираться
Методы похожи на функции. Они тоже пишутся со скобочками и в них тоже передаются аргументы. Отличаются они тем, что привязаны к объекту, для которого вызываются. В примере выше .replace() привязан к строке «Ваня — ученик 4А класса. Ваня очень любит печеньки.» . Он заменил в этой строке все кусочки, где написано “Ваня” на “Игорь”.
Методы придумали для того, чтобы привязывать функции к типу данных. Вы уже работали со строками и числами. Забегая вперёд, есть и другие типы данных: списки, множества, даже картинки! Функция замены кусочков строки на другие нужна только для строк, с числами такое не делают. Функция округления нужна только для чисел, строку нельзя “округлить”. Чтобы не гадать какая функция для каких типов данных — придумали методы, привязанные к этим типам точкой.
Если всё ещё не понятно:
Попробуйте бесплатные уроки по Python
Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.
Переходите на страницу учебных модулей «Девмана» и выбирайте тему.
Функции и методы в Python: передача функции в функцию. Декоратор
Эта статья посвящена теме декораторов в Python. Поговорим о том, что это такое, уделим особое внимание свойствам функций в Python, на базе которых реализована данная идея, а также рассмотрим декораторы, которые принимают аргументы и возвращают значение из функции.
Что надо знать о методах и функциях в Python?
Говоря о функциях в Python, нужно упомянуть два аспекта: 1) функция в Python — есть объект специального вида, который можно передавать в виде аргумента другим функциям; 2) внутри функций в Python вы можете создавать другие функции, а также вызывать их, возвращая результат посредством return.
Теперь давайте поговорим об этом подробнее.
Функция как объект в Python
В языке программирования Python часто практикуется передача одной функции в виде аргумента другой функции. Представьте, что есть список целых чисел, и вы желаете на его базе получить другой список с элементами, которые будут квадратами первого списка. Вот, как это можно реализовать в Python:
>>> # исходный список >>> a = [1, 2, 3, 4, 5] >>> # функция, которая возводит в квадрат переданное ей число >>> sq = lambda x: x**2 >>> # проверка работы функции в Python >>> print(sq(5)) 25 >>> # получение списка квадратов >>> b = list(map(sq, a)) >>> print(b) [1, 4, 9, 16, 25]В нашем примере мы передали функции map в виде первого аргумента функцию sq. Последняя будет по очереди применяться ко всем элементам нашего списка a.
Кроме того, в Python функция является специальным объектом, имеющим метод __call__() . Представьте, что мы создали следующий класс:
class DemoCall(): def __call__(self): return "Hello!"Объект такого класса в Python мы сможем вызывать как функцию:
>>> hello = DemoCall() >>> hello() 'Hello!'Функция внутри функции в Python
Функции в Python мы можем создавать, вызывать и возвращать из других функций. Кстати, на этом основана идея замыкания (closures) в Python.
Давайте создадим функцию, умножающую 2 числа:
def mul(a): def helper(b): return a * b return helperВ этой функции в Python реализованы два важных свойства: 1) внутри функции mul() мы создаём ещё одну функцию helper() ; 2) функция mul() возвращает нам функцию helper() в качестве результата работы.
Вызов этой функции в Python:
>>>mul(4)(2) 8Особенность заключается в том, что мы можем создавать на базе функции mul() собственные кастомизированные функции. Давайте создадим функцию в Python, умножающую на 3:
>>>three_mul = mul(3) >>>three_mul(5) 15В результате была построена функция three_mul() , умножающая на 3 любое переданное ей число.
Декоратор функции в Python
Конструктивно речь идёт о некоторой функции, в качестве аргумента которого выступает другая функция. Декоратор в Python добавляет дополнительный функционал к функции, не меняя её содержимое.
Создание
Представьте, что мы имеем пару простых функций в Python:
def first_test(): print("Test function 1") def second_test(): print("Test function 2")При этом мы желаем их дополнить таким образом, чтобы перед вызовом основного кода нашей функции печаталась строчка “Start function”, а в конце – строка “Stop function”.
Реализовать поставленную задачу можно несколькими методами. Во-первых, мы можем добавить необходимые строки в конец и начало каждой функции. Но вряд ли это удобно, ведь если мы пожелаем их убрать, придётся модифицировать тело функции.
Теперь поговорим о втором пути. Для начала создадим функцию:
def simple_decore(fn): def wrapper(): print("Start function") fn() print("Stop function") return wrapperТеперь нужно обернуть функции в оболочку:
first_test_wrapped = simple_decore(first_test) second_test_wrapped = simple_decore(second_test)Обратите внимание, что функции first_test и second_test не поменялись.
>>> first_test() Test function 1 >>> second_test() Test function 2Наши функции second_test_wrapped и first_test_wrapped обладают функционалом, который нам и нужен.
>>> first_test_wrapped() Start function Test function 1 Stop function >>> first_test_wrapped() Start function Test function 1 Stop functionТеперь, если надо, чтобы так работали функции с именами first_test и second_test, делаем следующее:
first_test = first_test_wrapped second_test = second_test_wrapped>>> first_test() Start function Test function 1 Stop function >>> second_test() Start function Test function 2 Stop functionВыполненные нами действия и являются реализацией идеи декоратора.
Правда, вместо строк:
def first_test(): print("Test function 1") first_test_wrapped = simple_decore(first_test) first_test = first_test_wrappedмы можем написать иначе:
@simple_decore def first_test(): print("Test function 1")В нашем случае @simple_decore – это не что иное, как декоратор функции.
Передаём аргументы в функцию с помощью декоратора
Бывает, что функция требует наличие аргумента, поэтому мы можем передать его через декоратор. Давайте создадим декоратор, принимающий аргумент и выводящий информацию о декорируемой нами функции и её аргументе.
def param_transfer(fn): def wrapper(arg): print("Start function: " + str(fn.__name__) + "(), with param: " + str(arg)) fn(arg) return wrapperЧтобы продемонстрировать работу, создадим функцию, выводящую квадратный корень переданного ей числа, а в качестве декоратора, укажем созданный param_transfer:
@param_transfer def print_sqrt(num): print(num**0.5)Теперь давайте выполним данную функцию с аргументом 4:
>>> print_sqrt(4) Start function: print_sqrt(), with param: 4 2.0Декораторы для методов класса в Python
С декоратором можно объявлять и методы классов. Давайте выполним модификацию декоратора param_transfer:
def method_decor(fn): def wrapper(self): print("Start method: " + str(fn.__name__)) fn(self) return wrapperТеперь приступим к созданию класса для представления 2-мерного вектора (математического). В классе определим метод norm() , выводящий модуль вектора.
class Vector(): def __init__(self, px = 0, py = 0): self.px = px self.py = py @method_decor def norm(self): print((self.px**2 + self.py**2)**0.5)Что же, осталось продемонстрировать работу нашего метода:
>>> vc = Vector(px=10, py=5) >>> vc.norm() Start method: norm 11.180339887498949Возвращаем результат работы функции через декоратор
Зачастую создаваемые функции выполняют возвращение какого-либо значения. Чтобы это стало возможным осуществить через декоратор, нужно специальным образом построить нашу внутреннюю функцию:
def decor_with_return(fn): def wrapper(*args, **kwargs): print("Start method: " + str(fn.__name__)) return fn(*args, **kwargs) return wrapperВозможно применение этого декоратора и для оборачивания функций, принимающих различные аргументы и возвращающие значение:
@decor_with_return def calc_sqrt(val): return val**0.5Осталось выполнить функцию calc_sqrt() с параметром 16:
>>> tmp = calc_sqrt(16) Start method: calc_sqrt >>> print(tmp)Чем метод отличается от функции в Python?
В отличие от функции, метод узко специализирован и может быть применен только к объектам, которые его поддерживают. Например, метод списков append() может быть применен только к ним. Применение данного метода к другим объектам, которые его не поддерживают (строки или кортежи) вызовет ошибку. Но есть и такие методы, которые хорошо работают с несколькими типами объектов, например метод count() может применяться к строкам, спискам или кортежам
13 февраля 2023
Метод по сути это та же функция, но так как она определена внутри класса, и первым её аргументом является self , то она становится связанным методом bound method , получившим доступ к атрибутам связанного объекта (экземпляра класса).
# Обычная функция: def greet(name): print(f'Hello, name>') class Person: # Инициализатор класса, требующий присваивать значение атрибута name при инстанцировании объекта def __init__(self, name): self.name = name # Связанный метод, имеющий доступ к атрибуту name: def greet(self): print(f'Hello , self.name>. ') bob = Person('Bob') # Вызов связанного метода класса: bob.greet() # => Hello , Bob. # Вызов функции, не имеющий доступа к атрибутам объекта: greet(bob) # => Hello, # Вызов обычной функции, которой можно передать любое значение: greet('Bob') # => Hello, Bob greet(23) # => Hello, 23 greet('apple') # => Hello, apple
