惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Blog — PlanetScale
Blog — PlanetScale
PCI Perspectives
PCI Perspectives
K
Kaspersky official blog
T
Tenable Blog
Help Net Security
Help Net Security
Vercel News
Vercel News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
F
Fortinet All Blogs
罗磊的独立博客
P
Palo Alto Networks Blog
爱范儿
爱范儿
Google DeepMind News
Google DeepMind News
T
Threat Research - Cisco Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
人人都是产品经理
人人都是产品经理
L
LangChain Blog
Recent Announcements
Recent Announcements
有赞技术团队
有赞技术团队
博客园_首页
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Help Net Security
S
Secure Thoughts
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Project Zero
Project Zero
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
V
V2EX
Last Week in AI
Last Week in AI
H
Heimdal Security Blog
U
Unit 42
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
SecWiki News
SecWiki News
量子位
博客园 - 【当耐特】
Martin Fowler
Martin Fowler
NISL@THU
NISL@THU
S
Securelist
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
云风的 BLOG
云风的 BLOG
I
Intezer
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - Franky
Cisco Talos Blog
Cisco Talos Blog
小众软件
小众软件
C
CXSECURITY Database RSS Feed - CXSecurity.com

Posts on WKLKEN THINKING

apisix 中的 lrucache apisix 中的服务发现机制 apisix 中的负载均衡 apisix etcd机制 聊聊框架 关于 k8s 的 zero downtime deployment 一些建议 apisix 遇到的一些问题 关于在除夕前一天换了一个洗衣机的故事 Django DRF 性能优化 DRF 的一些实践 Part1: Serializer DRF继承关系图 Better Code: 关于接口的灵活性 新的仓库: wklken/naming 缓存使用的一些经验 Better Code: 抽象: 可扩展性与可维护性的抉择 Better Code: 异常时, 该提示用户哪些信息? Better Code: 更好的异常日志打印 Go: some libs Go: go-redis/cache升级的坑 Go: logrus性能提升 Go: gin validation 远程办公的一点总结 Go: 开发过程中的一些bug 项目管理实践: 风险驱动开发 Go: 一种error wrap调用链处理方式 漫谈技术选型 Go: 基于 apitest 做handler层单元测试 Go: go-sql-driver interpolateparams参数优化 [分享]深度工作 你需要更多的思考时间 Django项目重构小结 工作七年小结: 学习,生活及其他 [分享]bash日常: bash-utils 极客时间推广海报 2017总结: 予时光以意义 k8s APIServer源码: api注册详细细节 k8s APIServer源码: api注册主体流程 k8s APIServer源码: 服务启动 k8s APIServer源码: go-restful框架 重构 - 读书笔记(Python示例) 写给新人的沟通建议 vim 杂谈 - 关于快速编辑 vim 杂谈 - 关于移动 读书笔记-重构: 章11 处理概括关系 读书笔记-重构: 章10 简化函数调用 读书笔记-重构: 章9 简化表达式 读书笔记-重构: 章8 重新组织数据 读书笔记-重构: 章7 在对象之间搬移特性 读书笔记-重构: 章6 重新组织函数 Python 代码规范小结 [分享]关于vim ElasticSearch集群部署文档 Logstash+ElasticSearch处理mysql慢查询日志 [分享]关于代码调试DE那些事 Logstash+ElasticSearch+Kibana- 实现相对通用的数据收集分析 ELK维护的一些点(二) [分享]Python源码剖析-数据结构 一些Centos Python生产环境的部署命令 摘录<<6个月学会任何一种外语>> ELK 维护的一些点 也许是一个新的开始 一些vim的个性化配置 读书笔记-调试九法 这段时间的一些想法 Python 源码阅读 - 垃圾回收机制 我为什么要写博客 APUE笔记-第一章 UNIX基础知识 Python源码阅读-闭包的实现 Python源码阅读-内存管理机制(二) Python源码阅读-内存管理机制(一) Python-基础-数据结构小结 '活动'设计的一些trick 一些简单的Python测试题 我的tmux配置及说明【k-tmux】 Review and Restart 工作四周年小结 vim插件: surround & repeat[成对符号编辑] vim插件: gundo[时光机] vim插件: expand-region[区域选中] vim插件: quickrun[快速执行] vim插件: trailing-whitespace[行尾空格处理] vim插件: closetag[成对标签补全] vim插件: ctrlp[文件搜索] vim插件: airline[状态栏增强] vim插件: theme[主题] vim插件: tagbar[大纲式导航] vim插件: nerdcommenter[快速注释] vim插件: rainbow_parentheses[括号高亮] vim插件: syntastic[语法检查] vim插件: delimitmate[符号自动补全] vim插件: matchit[成对标签跳转] vim插件: easy-align[快速对齐] vim插件: multiple-cursors[多光标操作] vim插件: vim-signature[快速标记跳转] vim插件: easymotion[快速跳转] vim插件: vundle[管理插件] Elasticsearch几个问题的解决 分享一份 Vim 简介PPT k-vim 更新9.0版本 关于知识管理工具的思考
Python 源码阅读 - 类型
2014-08-05 · via Posts on WKLKEN THINKING

这篇主要涉及Python对象的类型机制

有点绕, 一定要思维清晰的时候再看哦:)


一个例子

>>> a = 1
>>> a
1

>>> type(a)
<type 'int'>

#等价的两个
>>> type(type(a))
<type 'type'>
>>> type(int)
<type 'type'>

#还是等价的两个
>>> type(type(type(a)))
<type 'type'>
>>> type(type(int))
<type 'type'>

我们反向推导一个int对象是怎么生成的.


1. 首先, 定义一种类型叫PyTypeObject

代码位置 Include/object.h

定义

 typedef struct _typeobject {

  /* MARK: base, 注意, 是个变长对象*/
  PyObject_VAR_HEAD
  const char *tp_name; /* For printing, in format "<module>.<name>" */ //类型名
  Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ // 创建该类型对象时分配的内存空间大小


  // 一堆方法定义, 函数和指针
  /* Methods to implement standard operations */
  printfunc tp_print;
  hashfunc tp_hash;

  /* Method suites for standard classes */
  PyNumberMethods *tp_as_number;   // 数值对象操作
  PySequenceMethods *tp_as_sequence; // 序列对象操作
  PyMappingMethods *tp_as_mapping; // 字典对象操作

  // 一堆属性定义
  ....

} PyTypeObject;

说明

1. PyObject_VAR_HEAD
变长对象

2. const char *tp_name
tp_name, 类型名字符串数组

所有Type都是PyTypeObject的"实例": PyType_Type/PyInt_Type


2. 然后, 用PyTypeObject初始化得到一个对象PyType_Type

代码位置 Objects/typeobject.c

定义

PyTypeObject PyType_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  "type",                                     /* tp_name */
  sizeof(PyHeapTypeObject),                   /* tp_basicsize */
  sizeof(PyMemberDef),                        /* tp_itemsize */
  (destructor)type_dealloc,                   /* tp_dealloc */

  // type对象的方法和属性初始化值
  .....

};

说明

1. tp_name
类型名, 这里是"type"

2. PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT, 这个方法在 Include/object.h中,
等价于
        ob_refcnt = 1
        *ob_type = &PyType_Type
        ob_size = 0

即, PyType_Type的类型是其本身!

结构

第一张图, 箭头表示实例化(google doc用不是很熟找不到对应类型的箭头) PyType_Type

第二张图, 箭头表示指向 PyType_Type2

使用

# 1. int 的 类型 是`type`
>>> type(int)
<type 'type'>

# 2. type 的类型 还是`type`, 对应上面说明第二点
>>> type(type(int))
<type 'type'>

注意: 无论任何时候, ob_type指向的是 PyTypeObject的实例: PyType_Type/PyInt_Type…


3. 再然后, 定义具体的类型, 这里以PyInt_Type为例子

代码位置 Objects/intobject.c

定义

PyTypeObject PyInt_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  "int",
  sizeof(PyIntObject),
  0,

  // int类型的相关方法和属性值
  ....

  (hashfunc)int_hash,                         /* tp_hash */

};

说明

1. "int"
PyInt_Type的类型名是int

2.PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyInt_Type的

    *ob_type = &PyType_Type

结构

PyType_Type2

使用

>>> type(1)
<type 'int'>

>>> type(type(1))
<type 'type'>

4. 最后, 生成一个整数对象int

代码位置 Include/intobject.h

定义

typedef struct {
    PyObject_HEAD
    long ob_ival;
} PyIntObject;

结构

PyType_Type2

1. PyIntObject为整数类型

2. 声明一个整数后得到整数对象

3. 对象ob_type指向PyInt_type对象

到这里, 总结下

 1. 一切都是对象

 2. PyType_Type / PyInt_Type / PyString_Type ....等
 这些是`类型对象`, 可以认为是同级, 都是PyTypeObject这种`类型`的实例!

 3. 虽然是同级,
 但是其他PyXXX_Type, 其类型指向 PyType_Type
 PyType_Type 的类型指向自己, 它是所有类型的`类型`

 4. PyTypeObject 是一个变长对象

 5. 每个object, 例如PyIntObject都属于一种`类型`
 object初始化时进行关联

多态是如何实现的?

对象的多态, 例如hash

>>> hash(1)
1
>>> hash("abc")
1453079729188098211

从上面数据结构可以看到, 方法及属性, 在不同Type实例化时就确定了

PyTypeObject PyInt_Type = {
    ...
    (hashfunc)int_hash,                         /* tp_hash */
    ...
}


PyTypeObject PyString_Type = {
    ...
    (hashfunc)string_hash,                      /* tp_hash */
    ...
}

Python内部传递的是泛型指针PyObject *, 函数调用时, 找到其类型* ob_type, 然后调用

object -> ob_type -> tp_hash

即: 大量函数指针决定了该类型的具体行为


changelog

2014-08-05 first version