调用 object.method() 和 Class.method(object) 时幕后发生了什么?

2023-12-04

我对 Python 还很陌生,正在处理 OOP。我对何时使用对方法和类的调用有点困惑。下面的示例代码输出平均值,但是我很好奇什么时候从类调用与从现实世界的角度使用方法调用。我很确定这只是我可能尚未解决的问题,但对于何时使用其中一个而不是另一个有点困惑。

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

在你的例子中,没有什么区别。使用第一种方式。第二种方式使您看起来好像出于某种原因需要使用“后门”,例如,如果student_one实际上不是Student实例,但您想专门调用average的方法Student class.

如果一位经验丰富的 Python 开发人员要阅读您的代码,会看到Student.average(student_one)可能会让他们停顿一下,想知道为什么作者要使用 unboundaverage这里。这将是一种不寻常的风格,也许可能意味着可能会发生比实际情况更微妙的事情——一个绊脚石。

对于幕后发生的事情,第一种方法使用绑定方法第二种方式只使用普通的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

通过在类上使用该函数并显式传入实例,您基本上会执行与调用描述符自动执行的操作相同的操作。

为了更深入地了解方法是什么,文档中有此绑定过程的详细文档here.

* Just a fancy way of saying via the "." i.e. the dotted attribute access

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调用 object.method() 和 Class.method(object) 时幕后发生了什么? 的相关文章

随机推荐