python - CPython 解释器如何处理 OOP

标签 python c oop cpython

最近有 friend 问“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 解释器本身不是面向对象的,那么它如何处理对象之类的事情?

最佳答案

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


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

  • A类
  • 一个包含其属性的字典
  • 其他现在不相关的东西,比如 __weakref__

类也很简单。它有

  • 基类
  • 一个包含其属性的字典
  • 其他现在不相关的东西,比如类名。

当你用 class 语句定义一个类时,Python 会捆绑一个指向你选择的基类的指针(或者 object 如果你没有选择)并且一个包含您定义的方法的字典,这就是您的新类对象。有点像下面的元组

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)

属性赋值被转换为对象字典中的设置条目,因此 __init__ 中的赋值:

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

使字典以下列状态结束:

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

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

关于python - CPython 解释器如何处理 OOP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42451487/

相关文章:

python - 正则表达式:选择所有相邻的两个(主题标签)单词组

python - Jenkins 在后台运行脚本

C、检测fread是否会阻塞

c - 在c中为轮询添加回调函数

c++ - 从类成员生成容器

php - PHP WEB开发的N层结构有哪些层次及其作用?

python - 基于集合作为数据结构而不是列表的分布式任务队列

python - Tornado模板和Jinja2的区别

c - `char` 总是总是有 8 位吗?

python - 如何存储/缓存类中方法的值以便稍后在同一类的其他方法中使用?