Функции и методы в Python
В этом уроке вы узнаете о методах Python и различиях между функциями и методами.
Что такое методы в Python?
По определению, метод — это функция Python, привязанная к экземпляру класса.
Ниже определяется класс Request, содержащий функцию send():
class Request: def send(): print('Sent')
И вы можете вызвать функцию send() через класс Request следующим образом:
Request.send() # Sent
send() — это объект функции, который является экземпляром класса функции, как показано в следующем выводе:
print(Request.send)
Выход:
<function Request.send at 0x00000276F9E00310>
Тип отправки — функция:
print(type(Request.send))
Выход:
<class 'function'>
Следующее создает новый экземпляр класса Request:
http_request = Request()
Если вы отобразите http_request.send, он вернет привязанный объект метода:
print(http_request.send)
Выход:
<bound method Request.send of <__main__.Request object at 0x00000104B6C3D580>>
Таким образом, http_request.send не является такой функцией, как Request.send.
Проверим, является ли Request.send тем же объектом, что и http_request.send. Он вернет False, как и ожидалось:
print(type(Request.send) is type(http_request.send))
Причина в том, что тип Request.send — функция, а тип http_request.send — метод, как показано ниже:
print(type(http_request.send)) # <class 'method'> print(type(Request.send)) # <class 'function'>
Поэтому, когда вы определяете функцию внутри класса, это просто функция. Однако когда вы получаете доступ к этой функции через объект, функция становится методом. Следовательно, метод — это функция, привязанная к экземпляру класса.
Если вы вызовете функцию send() через объект http_request, вы получите ошибку TypeError следующим образом:
http_request.send()
Ошибка:
TypeError: send() takes 0 positional arguments but 1 was given
Поскольку http_request.send — это метод, привязанный к объекту http_request, Python всегда неявно передает объект методу в качестве первого аргумента.
Следующее переопределяет класс Request, в котором функция отправки принимает список аргументов:
class Request: def send(*args): print('Sent', args)
Следующий код вызывает функцию отправки из класса Request:
Request.send()
Выход:
Sent()
Функция send() не получает никаких аргументов.
Однако если вы вызываете функцию send() из экземпляра класса Request, аргументы не пусты:
http_request.send()
Выход:
Sent(<__main__.Request object at 0x000001374AF4D580>,)
В этом случае метод send() получает объект http_request, который является объектом, к которому он привязан.
Ниже показано, что объект, вызывающий метод send(), — это тот объект, который Python неявно передает этому методу в качестве первого аргумента:
print(hex(id(http_request))) http_request.send()
Выход:
0x1ee3a74d580 Sent(<__main__.Request object at 0x000001EE3A74D580>,)
Объект http_request аналогичен объекту, который Python передает методу send() в качестве первого аргумента, поскольку они имеют одинаковый адрес памяти. Другими словами, вы можете получить доступ к экземпляру класса в качестве первого аргумента внутри метода send():
Следующий вызов метода
http_request.send()
эквивалентен следующему вызову функции:
Request.send(http_request)
По этой причине метод объекта всегда имеет объект в качестве первого аргумента. По соглашению это называется self:
class Request: def send(self): print('Sent', self)
Если вы работали с другими языками программирования, такими как Java или C#, значение self совпадает с объектом this.