Python类型系统初步理解

Python类型系统初步理解

我们知道,在python中,一切皆是对象。每一个对象都是一种类型的实例,包括创造对象的类型其本身,也是一个对象,也是另一种有创造出类型的类型的实例。

以一个int类型的实例,整数123为例子,123的类型是int,int是一种类型,也就是一个类,但是它本身也是一个对象,是另一种类型的实例,这种类型是type,type是一种类型,也是一种类型的实例,这种类型是它本身。

>>> n = 123
>>> type(n)
<type 'int'>
>>> type(type(n))
<type 'type'>
>>> type(type(type(n)))
<type 'type'>

type是一个比较特殊的类型,type既是类型,也是对象,同时它是是其所代表的类型的实例。这样的类型,在python中称为元类。

同时,在python中,一切类型都是object类的子类,因此,一切对象都是object的实例,包括type,以及object本身。

那么,一个有趣的问题出现了:

  • type是object的实例
  • type是type的实例
  • object是object是实例
  • object是type的实例
>>> isinstance(type, object)
True
>>> isinstance(type, type)
True
>>> isinstance(object, object)
True
>>> isinstance(object, type)
True

object和type的这种关系在python语言层面比较难以理解。但是我们知道cpython是用c语言实现的,这些概念在c语言层面都有对应的代码实现,通过理解c语言层面的实现,可以较好的理解object和type的关系,以及python的对象模型。

在c语言层面,有一个结构体PyObject,“pyhton语言中一切皆是对象”这句话,反映到c语言层面,其等价表示是“一切python语言层面的对象,在c语言层面,都可以用一个指向PyObject结构体的指针来表示”。

PyObject结构体的代码(并非真实源码,进行了方便理解的简化)如下:

typedef struct _object {
    long ob_refcnt;
    struct _typeobject *ob_type;
} PyObject;

typedef struct _typeobject {
    PyObject ob_base;
    long ob_size;
    const char *tp_name;
    // ... (省略)
} PyTypeObject;

结构体PyObject就2项内容,一个引用计数器,用来进行垃圾收集的;一个指向另一个结构体的指针,用来表明这个对象是什么具体类型的,而这个结构体,其开头的部分,又是一个PyObject。

在c语言中,对于2个结构体A和B,如果B的开头一部分和A是一样的,那么它们的实例,在内存布局上,这一部分是一样的,从Python,Java等语言的概念上说,有点像继承。

#include <stdio.h>

typedef struct _person {
    char *name;
    int age;
} Person;

typedef struct _teacher {
    char *name;
    int age;
    char *course;
} Teacher;

void print_person(Person *person) {
   printf("I am %s, %d years old.\n", person->name, person->age);
}

int main() {
    Teacher t = {
        "tom",
        25,
        "Math"
    };
    print_person((Person *)&t);
    return 0;
}

在上面的例子中,Teacher结构体的开头部分是和Person一样的,Teacher可以当Person使用。同样的,在python中,无论是什么对象,在c语言层面的表示,都是一个结构体的实例,而这个结构体,其开头的部分一定是一个PyOject,所以,多有的对象都可以当Pyobject使用。反应在python语言层面就是所有的对象都是object的实例。

type和object间的关系可以用下面一段代码模拟:

#include <stdio.h>

typedef struct _object {
  long refcnt;
  struct _type_object *ob_type;
} PyObject;

typedef struct _type_object {
  long refcnt;
  struct _type_object *ob_type;
  const char *tp_name;
} PyTypeObject;

PyTypeObject py_type_type = {1, &py_type_type, "type"};

typedef struct _int_object {
  long refcnt;
  struct _type_object *ob_type;
  long value;
} PyInt;

PyTypeObject py_type_int = {1, &py_type_type, "int"};

PyInt int_10 = {1, &py_type_int, 10};

void print_type_name(PyObject *ob) {
  printf("<type '%s'>\n", ob->ob_type->tp_name);
}

int main() {
  print_type_name((PyObject *)&int_10);       // 相当于python中的type(10)
  print_type_name((PyObject *)&py_type_int);  // 相当于python中的type(int)
  print_type_name((PyObject *)&py_type_type); // 相当于python中的type(type)
  return 0;
}

转载于:https://my.oschina.net/u/1393056/blog/1999617

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值