深入理解 Python 虚拟机:集合(set)的实现原理及源码剖析

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

深入理解 Python 虚拟机:集合(set)的实现原理及源码剖析

在本篇文章当中主要给大家介绍在 cpython 虚拟机当中的集合 set 的实现原理(哈希表)以及对应的源代码分析。

数据结构介绍

typedef struct {
    PyObject_HEAD

    Py_ssize_t fill;            /* Number active and dummy entries*/
    Py_ssize_t used;            /* Number active entries */

    /* The table contains mask + 1 slots, and that's a power of 2.
     * We store the mask instead of the size because the mask is more
     * frequently needed.
     */
    Py_ssize_t mask;

    /* The table points to a fixed-size smalltable for small tables
     * or to additional malloc'ed memory for bigger tables.
     * The table pointer is never NULL which saves us from repeated
     * runtime null-tests.
     */
    setentry *table;
    Py_hash_t hash;             /* Only used by frozenset objects */
    Py_ssize_t finger;          /* Search finger for pop() */

    setentry smalltable[PySet_MINSIZE]; // #define PySet_MINSIZE 8
    PyObject *weakreflist;      /* List of weak references */
} PySetObject;

typedef struct {
    PyObject *key;
    Py_hash_t hash;             /* Cached hash code of the key */
} setentry;

static PyObject _dummy_struct;

#define dummy (&_dummy_struct)

上面的数据结果用图示如下图所示:

上面各个字段的含义如下所示:

  • dummy entries :如果在哈希表当中的数组原来有一个数据,如果我们删除这个 entry 的时候,对应的位置就会被赋值成 dummy,与 dummy 有关的定义在上面的代码当中已经给出,dummy 对象的哈希值等于 -1。
  • 明白 dummy 的含义之后,fill 和 used 这两个字段的含义就比较容易理解了,used 就是数组当中真实有效的对象的个数,fill 还需要加上 dummy 对象的个数。
  • mask,数组的长度等于 2n2^n2n,mask 的值等于 2n−12^n - 12n−1 。
  • table,实际保存 entry 对象的数组。
  • hash,这个值对 frozenset 有用,保存计算出来的哈希值。如果你的数组很大的话,计算哈希值其实也是一个比较大的开销,因此可以将计算出来的哈希值保存下来,以便下一次求的时候可以将哈希值直接返回,这也印证了在 python 当中为什么只有 immutable 对象才能够放入到集合和字典当中,因为哈希值计算一次保存下来了,如果再加入对象对象的哈希值也会变化,这样做就会发生错误了。
  • finger,主要是用于记录下一个开始寻找被删除对象的下标。
  • smalltable,默认的小数组,cpython 设置的一半的集合对象不会超过这个大小(8),因此在申请一个集合对象的时候直接就申请了这个小数组的内存大小。
  • weakrelist,这个字段主要和垃圾回收有关,这里暂时不进行详细说明。

创建集合对象

首先先了解一下创建一个集合对象的过程,和前面其他的对象是一样的,首先先申请内存空间,然后进行相关的初始化操作。

这个函数有两个参数,使用第一个参数申请内存空间,然后后面一个参数如果不为 NULL 而且是一个可迭代对象的话,就将这里面的对象加入到集合当中。

static PyObject *
make_new_set(PyTypeObject *type, PyObject *iterable)
{
    PySetObject *so = NULL;

    /* create PySetObject structure */
    so = (PySetObject *)type->tp_alloc(type, 0);
    if (so == NULL)
        return NULL;
    // 集合当中目前没有任何对象,因此 fill 和 used 都是 0
    so->fill = 0;
    so->used = 0;
    // 初始化哈希表当中的数组长度为 PySet_MINSIZE 因此 mask = PySet_MINSIZE - 1
    so->mask = PySet_MINSIZE - 1;
    // 让 table 指向存储 entry 的数组
    so->table = so->smalltable;
    // 将哈希值设置成 -1 表示还没有进行计算
    so->hash = -1;
    so->finger = 0;
    so->weakreflist = NULL;
    // 如果 iterable 不等于 NULL 则需要将它指向的对象当中所有的元素加入到集合当中
    if (iterable != NULL) {
        // 调用函数 set_update_internal 将对象 iterable 当中的元素加入到集合当中
        if (set_update_internal(so, iterable)) {
            Py_DECREF(so);
            return NULL;
 
Python源码Set集合对象底层解析 文章目录1、PySetObject对象2、PySetObject对象的创建3、PySetObject对象元素的插入4、PySetObject对象元素的删除5、PySetObject对象的扩容机制 1、PySetObject对象   之前我们解析了Python中的dict对象,我们知道在dict的底层实际上是一个hash table,是一种映射关系。同样,集合对象底层也是hash table,因此,对于细节的描述在这一节就不细说了。关于hash table可参照这篇文章。python的dict对象底层实现,话 阅读详情

相关推荐

带你走进python集合set内心世界

首先我来介绍一下setpythonset和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(), difference()和sysmmetric difference(对称差集)等数学运算. sets 支持 x in set, len(set),和 for x in set。作为一个无序的集合sets不记录元素位置或者插入点。因此,sets不支持 indexing, slicing, 或其它类序列(seq

pythonxiaopeng的博客 683

Python数据结构(三)set使用和原理

1. set是什么? 数学上,把set称做由不同的元素组成的集合集合set)的成员通常被称做集合元素(set elements)。Python把这个概念引入到它的集合类型对象里。集合对象是一组无序排列的可哈希的值。集合关系测试和union、intersection等操作符在Python里也同样如我们所预想地那样工作。 2. set特点 集合中的元素有三个特征: 确定性:集合中的元素必须是确...

Mr番茄蛋的博客 6421

SSRF漏洞深度解析:从协议原理到云环境攻防实战

服务器端请求伪造(SSRF)是一种常见且危害巨大的网络安全漏洞,其核心原理在于服务器过度信任客户端输入,并以自身身份发起非预期的网络请求。从技术实现层面看,SSRF通常源于应用程序未对用户提供的URL参数进行严格校验,直接使用网络库发起请求,并可能支持多种危险协议如file://、dict://和gopher://,从而允许攻击者读取本地文件、探测内网服务甚至攻击内部系统。在云原生和容器化环境中,SSRF的攻击价值被进一步放大,攻击者可通过访问云元数据服务(如169.254.169.254)窃取临时凭证,或

cuk0051的博客 394

Python-set的使用

Python-set的使用

qq_51010919的博客 743

python集合set原理及其操作

为了保持操作效率,在达到某个阈值时,Python 会自动增加存储空间,并重新计算所有已存储对象的位置。当你向集合添加一个元素时,Python 会首先计算该元素的哈希值(hash value),这个值决定了该元素在内部数据结构中的存储位置。Python 中的集合set)是一个无序的不重复元素序列。Python 中的集合set)是基于哈希表实现的。由于 set 是无序的,因此无法确定哪个是“下一个”被删除的项。找出只存在于其中一个 set 中而不同时存在于两个 sets 中的所有项。

瑞瑞的博客 3725

反序列化漏洞攻防实战:从原理到企业级纵深防御体系建设

序列化与反序列化是分布式系统和数据持久化的核心技术,它允许对象在网络传输或存储前转换为字节流,接收端再将其还原。其安全风险源于反序列化过程会执行对象初始化逻辑,若攻击者可控输入数据,便可构造恶意字节流触发危险方法链(Gadget Chain),导致远程代码执行。这种对数据结构而非内容失去控制的风险,在Java、.NET等生态中尤为突出,常因引入存在危险方法的第三方库(如Apache Commons Collections)而暴露。在攻防演练和实战中,反序列化漏洞因其高危害性成为红队突破和蓝队布防的焦点。有效

weixin_30333885的博客 341

JavaGuide核心内容体系:从基础到进阶的完整学习路径

本文系统梳理了Java从基础到高级的完整知识体系,涵盖Java基础语法、集合框架、并发编程、JVM原理及版本新特性。首先详细解析了Java语言特性、数据类型、面向对象编程和异常处理机制;接着深入探讨了集合框架结构、HashMap实现原理、并发编程核心机制和线程池工作原理;然后分析了JVM内存模型、垃圾回收算法及性能优化策略;最后概述了Java从JDK 8到21的重要版本演进和技术发展趋势,为开发

gitblog_00384的博客 931

使用现代C++开发GBA游戏:Butano引擎入门与实践指南

在嵌入式游戏开发领域,GBA(Game Boy Advance)因其经典的硬件架构和有限的性能资源,成为学习底层图形编程和性能优化的绝佳平台。其核心原理涉及ARM7TDMI处理器、基于图块(Tile)和精灵(Sprite)的图形系统,以及严格的内存与CPU周期管理。掌握这些技术不仅能深入理解计算机图形学基础,更能锤炼极致的代码优化能力。现代C++标准(如C++17/20)的引入,通过智能指针、RAII等特性,显著提升了资源管理的安全性与开发效率。Butano引擎正是这一技术价值的体现,它将现代C++与GBA

weixin_34242331的博客 446

Java面试核心考点解析:从基础语法到JVM调优与高并发实战

在Java开发领域,掌握核心原理是构建稳健应用的基础。从Java语法基础到JVM内存模型,理解底层机制有助于优化程序性能与资源管理。集合框架如HashMap的扩容机制与并发安全实现,以及多线程环境下的锁优化与线程池管理,是提升系统吞吐量的关键技术。这些知识不仅在日常开发中频繁应用,更是面试中区分工程师功底的核心考点。本文聚焦于Java面试中的高频问题,深入剖析equals()与hashCode()的契约、ConcurrentHashMap的线程安全实现、以及JVM垃圾回收算法等热点话题,帮助开发者系统性地构

weixin_30878501的博客 392

Apache Tomcat Ghostcat漏洞深度解析:从AJP协议缺陷到RCE实战

AJP协议作为Apache Tomcat与前端Web服务器间的高性能二进制通信协议,旨在优化集群环境下的数据传输效率。其核心原理在于通过序列化请求属性来提升处理速度,然而,协议实现中对客户端传入的请求属性缺乏严格校验,构成了严重的安全缺陷。这一技术漏洞使得攻击者能够滥用请求属性控制机制,其直接技术价值在于揭示了默认配置下隐藏的攻击面,对系统安全构成了严峻挑战。在应用场景上,该缺陷常被利用于企业内部网络或云服务器中未正确配置防火墙的Tomcat实例,攻击者无需认证即可通过默认开启的8009端口实施入侵。具体到

weixin_33937913的博客 369

长沙红胖子Qt·西安(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...

长沙红胖子 Qt・西安,本人拥有省级科研团队从业背景,研发团队产出所有项目、产品方案和研发无分包、无外包、无AI代笔,长期深耕双一流体系高精尖技术配套研发。博客主动剥离复杂底层工况机理,专注沉淀高端、特种行业领域Qt工程化落地实战经验。所有内容均为个人梳理总结的通用性工程方法论,只输出可公开的普适技术思路。

长沙红胖子 Qt・西安|省级科研团队从业背景,深耕双一流体系高精尖技术配套研发|剥离高精尖机理,沉淀高端特种行业领域 Qt 工程化落地经验|博文仅分享通用技术总结,输出公开普适工程思路。 163万+

从工具使用者到开发者:网络安全渗透测试工具开发与漏洞挖掘核心技术解析

在网络安全领域,渗透测试是评估系统防御有效性的关键手段。其核心原理在于模拟攻击者行为,通过主动探测和分析来发现潜在的安全弱点。随着网络环境日益复杂,通用自动化扫描工具在应对定制化业务逻辑和新型防御机制时往往力不从心,这凸显了掌握定制化工具开发技术的工程价值。从概念上讲,工具开发不仅提升了测试的针对性和效率,更是实现深度漏洞挖掘的基础。具体到技术实现,现代渗透测试工具通常采用分层架构,涵盖数据采集、核心引擎、插件扩展和交互报告等模块。在漏洞挖掘方面,模糊测试(Fuzzing)作为自动化挖掘的利器,通过覆盖率引

weixin_34393428的博客 445

每周小记——JVM

本文剖析JVM核心机制:详述内存模型(堆、方法区、栈)及垃圾回收算法(标记-清除/复制/压缩)、分代策略与GC类型(Minor/Major/FullGC);解析类加载机制(双亲委派模型、加载/链接/初始化过程及三类加载器差异);阐述执行引擎(JIT编译、热点探测、逃逸分析);对比现代收集器(G1/ZGC/Shenandoah)及CMS优劣;探讨性能调优关键(吞吐量与延迟平衡、内存分配策略)。为Java性能优化提供理论支撑。

weixin_57655687的博客 1565

KeySteer 0.9.1:基于Windows OCR的GUI自动化新思路,解决非标控件定位难题

GUI自动化是软件测试和流程自动化的关键技术,其核心在于对界面元素的精准定位与操作。传统方法依赖于可访问性树或控件句柄,但在面对老旧应用、游戏界面或虚拟机环境时,这些方法往往失效。KeySteer 0.9.1 创新性地利用了Windows系统自带的OCR引擎,将屏幕上的可视文字作为交互锚点,实现原理上的突破。该工具通过调用Windows原生API,将视觉识别与指针控制进行系统级、低延迟的绑定,其技术价值在于为自动化测试和辅助操作提供了全新的解决方案。在应用场景上,它特别适用于处理大量非标界面、进行跨语言

weixin_33991418的博客 432

Windows权限提升自动化检测工具Sherlock实战指南

权限提升是系统安全评估中的核心环节,指低权限用户通过利用系统漏洞或配置弱点获取更高权限的过程。其原理通常基于操作系统安全机制的缺陷,如服务配置错误、权限继承漏洞或未修补的安全更新。掌握权限提升技术对于渗透测试、红队演练和安全审计具有重要价值,能帮助安全人员快速识别系统脆弱点。在实际应用中,自动化检测工具能显著提升效率,例如通过预定义规则扫描系统状态、比对补丁信息、检查服务权限配置等。本文聚焦于Windows环境下的权限提升自动化检测,深入解析Sherlock工具的核心检测逻辑,涵盖MS16-032、未引用服

weixin_34166472的博客 381

【信息科学与工程学】【运营科学】第二篇 C4信息与通信网络运营 (C4) ——数据中心网络运营04

典型值:λ1​∈[−0.02,−0.01], λ2​∈[−0.01,0], η1​,η3​∈[0.1,0.3], η2​,η4​∈[0.05,0.15]参数:δ1​∈[−0.8,−0.3], δ2​∈[−0.5,−0.2], δ3​∈[−0.4,−0.1], δ4​∈[−0.6,−0.2]参数:φ1​∈[0.1,0.3], φ2​∈[−0.2,−0.05], φ3​∈[−0.1,0.1], φ4​∈[−0.3,−0.1]参数:α∈[0.3,0.6], β∈[0.2,0.4], γ∈[0.01,0.03]

weixin_49199313的博客 1059

python基础之集合set详解

python集合使用大括号{}或者set()函数创建

kymppcds的博客 1534

python3.7源码分析-集合(set)

python集合 set是无序且不重复的集合,是可变的,通常用来从列表中删除重复项以及计算数学运算,如交集、并集、差分和对称差分等集合操作。set 支持 x in set, len(set),和 for x in set。作为一个无序的集合set不记录元素位置或者插入点。因此,sets不支持 indexing, 或其它类序列的操作。 python集合概述 在set中,对应的set的值的存储是通过...

qq_33339479的博客 2511
上一篇: 偷偷告诉你!与其辞职,不如用Python搞月入过万的副业兼职
下一篇: 聊聊学python转行、具体学习方法、自学python用于办公、写爬虫等……
Python_P叔
博客等级 码龄3年 5371粉丝 827原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值