В вашем примере разницы нет. Используйте первый способ. Второй способ заставляет вас выглядеть так, как будто вам нужно по какой-то причине использовать «заднюю дверь», например, если type(student_one) is not Student
, но вы хотели специально вызвать метод average
Student
class.
Для того, что происходит за кулисами, первый способ использует связанный метод , а второй способ просто использует обычный function .
>>> Student.average
<function __main__.Student.average(self)>
>>> student_one.average
<bound method Student.average of <__main__.Student object at 0xcafef00d>>
Связанный метод - это просто функция, которая привязана к экземпляру через протокол дескриптора *, и экземпляр ("self") передается какпервый позиционный аргумент неявно:
>>> student_one.average.__self__ is student_one
True
>>> student_one.average.__func__ is Student.average
True
Используя функцию класса и явно передавая экземпляр, вы, по сути, делаете то же самое, что и вызов дескриптора автоматически.
Для более глубокого понимания того, что такое метод, есть подробная документация этого процесса связывания в документах здесь .
* Просто причудливый способ сказать через "."то есть пунктирный атрибут доступа