Reputation: 39
I am pretty new to Python and am tackling OOP. I am a bit confused as to when to use calls to methods and classes. The sample code below outputs the average, however I am curious as to when you would use calling from the Class vs methods from a real-world perspective. I'm pretty sure this is just something that I may have yet to tackle, but it's just been a bit of a confusion as to when I would use one over the other.
class Student:
def __init__(self, new_name, new_grades):
self.name = new_name
self.grades = new_grades
def average(self):
return sum(self.grades) / len(self.grades)
student_one = Student('Test User', [70, 88, 90, 99])
# object.method()
print(student_one.average())
# Class.method(object)
print(Student.average(student_one))
Upvotes: 2
Views: 309
Reputation: 362557
In your example, there is no difference. Use the first way. The second way makes it appear as though you need to use "the back door" for some reason, for example if student_one
was not actually a Student
instance but you wanted to specifically call the average
method of the Student
class.
If an experienced Python developer were to read your code, seeing Student.average(student_one)
may make them pause for a moment and wonder why the author wants to use the unbound average
here. It would be an unusual style, and perhaps could imply that there may be something more subtle happening than there really was - a stumbling block.
For what's going on behind the scenes, the first way uses a bound method and the second way just uses a normal function.
>>> Student.average
<function __main__.Student.average(self)>
>>> student_one.average
<bound method Student.average of <__main__.Student object at 0xcafef00d>>
A bound method is just a function which is bound to an instance, via descriptor protocol*, and the instance ("self") is passed as the first positional argument implicitly:
>>> student_one.average.__self__ is student_one
True
>>> student_one.average.__func__ is Student.average
True
By using the function on the class and passing in the instance explicitly, you essentially do the same thing as an invocation of the descriptor does automatically.
For a deeper understanding of what a method is, there's detailed documentation of this binding process in the docs here.
* Just a fancy way of saying via the "." i.e. the dotted attribute access
Upvotes: 4