В чем разница между связанным методом и функцией?

#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)