最近有 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/