2017-02-25 72 views
3

一位朋友最近问道:“CPython解释器如何实际处理OOP(面向对象编程)?”。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解释器如何处理对象?

回答

5

Python的OOP实现的全部复杂性远远超出了一个堆栈溢出答复的范围,但它可以提供一个概述。这将覆盖很多细节,如元类,多继承,描述符和C级API。不过,它应该让你了解为什么实施这样的事情是可能的,以及对它如何完成的总体印象。如果您想了解详细信息,请浏览CPython source code


喜欢你Person类的实例对象包括以下内容:

  • 的字典持有其属性
  • 其他的东西,这是不相关的,现在,像__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水平,这个纪录是差不多,但不完全,实现为一个结构。)


当您创建类的实例,巨蟒捆绑在一起的一个指针类,并为新字典实例的属性,这就是你的实例。它有点像下面的元组:

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(),巨蟒看起来personOne的字典,那么它的类的字典,那么它的父类的字典,等等,直到它找到了'getInfo'键的条目。关联的值将是getInfo方法。如果该方法在类字典中找到,则Python将插入personOne作为第一个参数。 (知道如何插入该参数的详细信息在descriptor protocol中。)

6

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