【问题标题】:How does the CPython Interpreter handle OOPPython解释器如何处理OOP
【发布时间】:2017-07-16 01:03:12
【问题描述】:

最近有朋友问“CPython 解释器实际上是如何处理 OOP(面向对象编程)的?”。

这个问题最终让我感到困惑,因为我知道 C 不是面向对象的语言。

我试过Googling it,搜索StackOverflow,甚至阅读CPython Wiki。但我找不到任何有用的东西。

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def getInfo(self):
        return "Name: " + self.name + "\nAge: " + str(self.age)

# How the heck does CPython handle this?
personOne = Person("Bob", 34)
personTwo = Person("Rob", 26)

print( personOne.getInfo() )
print( personTwo.getInfo() )

所以现在我真的很想知道!如果 CPython 解释器本身不是面向对象的,那么 CPython 解释器如何处理诸如对象之类的事情?

【问题讨论】:

    标签: python c oop cpython


    【解决方案1】:

    Python 的 OOP 实现的全部复杂性远远超出了 Stack Overflow 答案的范围,但可以提供一个概述。这将掩盖很多细节,例如元类、多重继承、描述符和 C 级 API。尽管如此,它应该让您了解为什么可以实现这样的事情,以及对它是如何完成的总体印象。如果您想了解完整的详细信息,请浏览CPython source code


    Person 类的实例这样的对象包含以下内容:

    • 一类
    • 包含其属性的字典
    • 目前不相关的其他内容,例如 __weakref__

    类也很简单。它有

    • 基类
    • 包含其属性的字典
    • 目前不相关的其他内容,例如类名。

    当您使用class 语句定义一个类时,Python 会捆绑一个指向您选择的基类的指针(或者 object,如果您没有选择一个)和一个保存您定义的方法的 dict,那就是你的新类对象。有点像下面的元组

    Person = (object,
              {'__init__': <that __init__ method you wrote>,
               'getInfo': <that getInfo method you wrote>},
              those irrelevant bits we're glossing over)
    

    但不是元组。 (在 C 级别,这条记录几乎但不完全是作为结构实现的。)


    当您创建类的实例时,Python 将指向您的类的指针和用于实例属性的新字典捆绑在一起,这就是您的实例。有点像下面的元组:

    personOne = (Person, {}, those irrelevant bits we're glossing over)
    

    但同样,不是元组。同样,它几乎但不完全是作为 C 级别的结构实现的。

    然后它运行 __init__,传递 __init__ 新实例以及您提供给类的任何其他参数:

    Person.__init__(personOne, "Bob", 34)
    

    属性赋值被翻译成在对象的dict中设置条目,所以__init__中的赋值:

    def __init__(self, name, age):
        self.name = name
        self.age = age
    

    导致 dict 最终处于以下状态:

    {'name': 'Bob', 'age': 34}
    

    当您调用personOne.getInfo() 时,Python 会查找personOne 的字典,然后是其类的字典,然后是其超类的字典,等等,直到找到'getInfo' 键的条目。关联的值将是getInfo 方法。如果在类字典中找到该方法,Python 将插入 personOne 作为第一个参数。 (它如何知道插入该参数的详细信息在descriptor protocol 中。)

    【讨论】:

      【解决方案2】:

      这里有一个小的思想实验:你的 CPU 根本不是“面向对象的”。相反,它只能执行诸如“将寄存器 1 添加到寄存器 2 并将结果放入寄存器 3”和“如果寄存器 5 大于零,则执行此 goto 语句”之类的指令。然而不知何故,CPU 可以运行 Python 和其他面向对象的语言。怎么样?

      【讨论】:

        猜你喜欢
        • 2017-04-09
        • 1970-01-01
        • 1970-01-01
        • 2011-02-06
        • 1970-01-01
        • 1970-01-01
        • 2019-02-13
        • 2013-06-18
        • 1970-01-01
        相关资源
        最近更新 更多