调用 object.method() 和 Class.method(object) 时,幕后发生了什么? [英] What is happening behind the scenes when calling object.method() and Class.method(object)?

查看:50
本文介绍了调用 object.method() 和 Class.method(object) 时,幕后发生了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

班级学生:def __init__(self, new_name, new_grades):self.name = new_nameself.grades = new_grades定义平均值(自我):返回总和(self.grades)/len(self.grades)student_one = Student('测试用户', [70, 88, 90, 99])# object.method()打印(student_one.average())# 类.方法(对象)打印(Student.average(student_one))

解决方案

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

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

对于幕后发生的事情,第一种方法使用 bound 方法 第二种方法只使用普通的 功能.

<预><代码>>>>学生平均<函数__main__.Student.average(self)>>>>student_one.average<绑定方法Student.average of <__main__.Student object at 0xcafef00d>>

绑定方法只是一个绑定到实例的函数,通过 描述符协议*,并且实例(self")作为第一个位置参数隐式传递:

<预><代码>>>>student_one.average.__self__ 是 student_one真的>>>student_one.average.__func__ 是 Student.average真的

通过在类上使用函数并显式传入实例,您基本上可以做与自动调用描述符相同的事情.

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

* 只是一种通过."来表达的奇特方式.即点属性访问

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

解决方案

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

这篇关于调用 object.method() 和 Class.method(object) 时,幕后发生了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆