#python #function #class #object #methods
#python #функция #класс #объект #методы
Вопрос:
Рассмотрим следующий класс:
class Employee:
def __init__(self,first,last,pay):
self.first=first;self.last=last
self.pay=pay
self.email=first.lower() '.' last.lower() "@company.com"
def fullname(self): return "{} {}".format(self.first, self.last)
если я получу доступ к методу fullname следующим образом:
em1.fullname #assume em1 object already exists
Я получаю следующий вывод:
<bound method Employee.fullname of <__main__.Employee object at 0x7ff7883acc88>>`
Однако, если я получу доступ к методу fullname следующим образом:
Employee.fullname
Я получаю следующий вывод: <function Employee.fullname at 0x7ff7883c9268>
Почему существуют два разных определения для одной и той же функции / метода? Я все еще обращаюсь к тому же объекту метода / функции в памяти, верно?
Ответ №1:
При доступе fullname
через экземпляр em1.fullname
вы получаете связанный метод, что означает версию, fullname
которая автоматически получает em1
в качестве своего первого аргумента.
Таким образом, вы можете вызывать em1.fullname()
без необходимости передавать какой-либо явный аргумент. Но если вы вызовете Employee.fullname()
, вы получите ошибку из-за отсутствия аргумента self
.
Это применимо даже тогда, когда вызов метода отделен от доступа к атрибуту:
bound = em1.fullname
unbound = Employee.fullname
bound() # OK, first argument is em1
unbound() # Error, no argument for self
unbound(em1) # OK, first argument supplied
Комментарии:
1. В чем разница между
em1.fullname
иem1.fullname()
then?2.
em1.fullname
является ссылкой на связанный метод.em1.fullname()
это вызов связанного метода.3. Так
em1.fullname
это похоже на «потенциальную» функцию? У него есть все параметры, необходимые для вычисления возвращаемого значения, но его не просят вызвать. Кроме того, поскольку у него есть необходимые параметры, он принципиально отличается от функции, у которой нет необходимых параметров?4.
em1.fullname
фактически это функция, которая не требует аргументов.em1.fullname()
— это вызов этой функции, которая запускает вызовEmployee.fullname(em1)
.
Ответ №2:
Я все еще обращаюсь к тому же объекту метода / функции в памяти, верно?
Совершенно определенно нет, и это очевидно из предоставленных вами выходных данных. Первый работает на 0x7ff7883acc88
, а второй на 0x7ff7883c9268
.
Первый принадлежит экземпляру, в то время как второй принадлежит самому Employee
классу.
Ответ №3:
Вы можете получить доступ к той же функции.
Однако для вызова функции с em1.fullname
вам просто нужно:
em1.fullname()
Но с помощью Employee.fullname
вам нужно указать self
аргумент, и вам понадобится:
Employee.fullname(em1)