当c没有继承时,每个对象与pyObject有什么关系

时间:2019-07-16 13:41:47

标签: python

我一直在查看python的源代码。看起来每个对象都派生自PyObject。但是,在C语言中,没有面向对象编程的概念。那么,在没有继承的情况下如何实现呢?

2 个答案:

答案 0 :(得分:2)

您关于C没有面向对象编程的概念的主张是错误的。 C没有明确地具有OOP,并且它并不是在考虑到它的基础上构建的,但是您当然可以在不花费太多精力的情况下使用C来进行OOP。这是因为利用了C实际上并不真正在乎结构的内部内存布局是什么样的事实。如果您有两个结构:

struct A {
    int field1;
    int field2;
    double field3;
};

struct B {
    A fieldA
    int field4;
    float field5;
};

这实际上使B成为A的子类。毕竟,B的内存布局的第一部分与A的内存布局完全相同。如果将其作为空指针传递,则可以进行类型转换,而C并不在乎:

void doSomething(void *obj) {
    int field2value = ((A*) obj).field2;
    float field5value = ((B*) obj).field5;
    printf("field2: %d\nfield5: %f", field2value, field5value);
}

您告诉C您认为是什么类型,void指针应该是什么,它就实现了。如果您猜错了,就会得到意外的行为,或者如果您认为它应该大于实际类型的类型,就会出现段错误。您可以使用它笨拙地实现继承:

void constructA(void* obj) {
    a = (A*) obj
    a.field1 = 4;
    a.field2 = 2;
    a.field3 = 3.14;
}

void constructB(void *obj) {
    constructA(obj);
    b = (B*) obj;
    b.field4 = 7;
    b.field5 = 6.28;
}

int main() {
    B *myObj = malloc(sizeof(B));
    constructB(myObj);
    free(myObj);
}   

如果A的变量之一是函数指针,那很好。该函数指针与其余的指针一起传递。毕竟,您可以从任何地方调用它。您可以在“子类”中替换其功能,然后稍后再调用原始版本,如果您实际上并未覆盖其在内存中的位置-否则,您可以让替换项手动调用它指向的功能

许多高级C代码使用相似的模式来复制继承的思想(或者,仅使用C ++,它可以优化整个布局并将其抽象化,以便程序员可以使用更直观的语法)。 / p>


但是即使如此,这仍然是关键。关于python,我最喜欢的事情之一是在最深层次上的一致性- everything 是一个对象,所有对象基本上都是哈希表,其名称指向引用。 Python的鸭子类型化想法之所以起作用,不是因为底层的C代码具有继承的任何想法,而是因为该代码只是寻找具有正确名称的属性,如果找到了正确的名称,它将使用它。

那么python中的子类与上面的相同-一个新的python对象,该对象从上至下进行初始化,并随着距离底部越来越近,在hashmap中添加了越来越多的字段。

答案 1 :(得分:2)

构成面向对象编程范例的原因是作为数据集模板的“类”与将对此数据集进行操作的函数之间的关系。并且,继承机制是从类到祖先类的关系。

但是,这些关系并不依赖于特定的语言语法-只是它们始终存在。

因此,没有什么可以阻止人们在C语言中进行“面向对象”的工作,实际上,即使没有OO框架,有组织的库也最终变成了与OO相关的组织。

碰巧,Python对象系统完全是用纯C定义的,对象具有__class__插槽,该插槽使用C指针指向其类-仅当从Python“掠过”该类的全部表示时感到不满。依次类具有__mro____bases__插槽,它们指向超类的不同排列(这次的指针是针对从Python视为序列的容器)。

因此,当使用Python运行时的定义和API在C语言中进行编码时,可以像在Python中进行编码一样使用OOP-实际上,可以使用可与Python语言互操作的Python对象。 (cython项目甚至可以将Python语言的超集转换为C,并提供透明的方式来编写使用Python语法的本地代码)

C还提供了其他框架,它们提供了不同的OOP系统,这些框架具有相同的一致性,例如glib-定义了“ gobject”,并且是所有GTK +和GNOME应用程序的基础。