首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么PyImport_ImportModule返回一个引用计数为3而不是1的PyObject*

PyImport_ImportModule函数是Python中用于动态导入模块的函数。它返回一个PyObject指针,该指针指向导入的模块对象。在这个特定的情况下,返回的模块对象的引用计数为3而不是1,这是因为在导入模块的过程中,涉及到了多个引用。

具体来说,返回的模块对象的引用计数为3的原因如下:

  1. 第一个引用计数是由PyImport_ImportModule函数本身创建的。在调用该函数时,Python解释器会创建一个模块对象,并将其引用计数设置为1。
  2. 第二个引用计数是由sys.modules字典中的条目创建的。sys.modules是一个字典,用于缓存已导入的模块对象。当导入一个模块时,如果该模块已经在sys.modules中存在,Python解释器会直接返回该模块对象,并将其引用计数增加1。这样可以避免重复导入同一个模块。
  3. 第三个引用计数是由模块对象在全局命名空间中的引用创建的。当导入一个模块后,该模块的全局变量会被添加到当前命名空间中,从而可以通过模块名访问这些变量。这些全局变量对应的对象也会增加对模块对象的引用,因此模块对象的引用计数会再次增加1。

综上所述,PyImport_ImportModule返回的模块对象的引用计数为3。这是因为在导入模块的过程中,涉及到了PyImport_ImportModule函数本身的引用、sys.modules字典中的引用以及全局命名空间中的引用。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++ 调用Python3

环境必须与目标程序类型相同,比如你在VS 中新建一个Win32项目,在引用Python环境时候就需要引用32位版本Python 这些准备工作做完后在调用Python前先调用Py_Initialize...这个函数会返回一个Python对象指针,在C++中表示PyObject。...这里需要注意一个问题就是Python3废除了在2中普通字符串,它将所有字符串都当做Unicode了,所以在调用3时候需要将所有字符串转化为Unicode形式不是像之前那样转化为String。.../ 参数一设为4 PyObject* arg2 = PyInt_FromLong(3); // 参数二设为3 PyTuple_SetItem(args, 0, arg1);...PyTuple_SetItem(args, 1, arg2); 或者如果元组中都是简单数据类型,可以直接使用 PyObject* args = Py_BuildValue(4, 3); 这种方式来创建元组

2.2K50

听说你会玩 Python 系列 3

PyObject 是计算机分配一块内存,其下有类型、大小和引用计数等属性。引用计数是说多少个变量名“指向”该对象,当引用计数零时,意味着没有任何变量名引用,因此可以被回收。...[3hcut3z4k2.png] ---- 创建一个新变量 y 并等于 x 表面上是敲入 y = x 时,实际发生是: 将 y 和 x 指向同样对象 PyObject 将该对象 PyObject引用计数加...1 将旧对象 PyObject (即 x 指向对象) 里引用计数1 [mhl40h3v1g.png] ---- 由上图可知,在 Python 中,即便对于一个简单整数,它不单单包含其值,还包含其类型...但为什么改变 y 不是改变 x 呢?原因在于改变 y 时新建了一个1033 PyObject,并将 y 指向它, x 还是指向原来值 1032 PyObject。...,叫做 l 将 l 指向新对象 PyObjectPyObject引用计数1 根据上述流程,当更改列表中元素,只是新创建其元素 PyObject没有新创建列表本身 PyObject

57210

在C++中调用Python

Python安装 为了使用Python.h这个扩展项,我们需要安装一个python*-dev不是python*,这两者略有区别,下面的案例展示是在Ubuntu20.04下安装python3.9-dev...正在选中未选择软件包 zlib1g-dev:amd64。 准备解压 .../zlib1g-dev_1%3a1.2.11.dfsg-2ubuntu1.2_amd64.deb ......这一章节目的主要是解决IDE中报错问题,还不是最终运行中出现问题,因为运行时我是通过命令行执行g++来运行不是直接用IDE来跑。...: # pysplit.py def sp(string): return string.split() 这是一个非常简单函数,但是我们在调用时候就直接返回一个错误: dechin@ubuntu2004...格式,比如**args,类似**kwargs则是打包成一个字典格式,类似的功能在这篇博客中有所介绍。

3.9K30

秒啊!Python 信号量源码拆解来了!

信号位表示 Linux下可以通过/proc目录来确定进程对信号处理方式 [3],下面是一个普通 Python 进程采样 $ cat /proc/16107/status | grep Sig SigQ...解释器负责与操作系统相关信号接口交互 解释器实现信号处理接口模块(C)加载 解释器实现signal模块引用信号处理接口模块(C) 源码解读 信号如何初始化 下面我们将从信号初始化开始一点点探索signal...module) { return -1; } Py_DECREF(module); return 0; } PyOS_setsig是对OS层信号量封装,这块代码也可以解释为什么本文起始...通常是由于读取进程关闭了IPC通道文件描述符产生 SIGXFZ:这个没找到具体用途,尴尬脸TODO SIGXFSZ:当进程试图使用write()或truncate()函数,但却超出了进程文件大小资源限制...此外,只有主线程被允许设置一个信号处理器。

1.1K40

Python垃圾回收机制

17行又多了一个数据字段,叫做元素个数,这个结构体。 以上源码是Python内存管理中基石,其中包含了: 2个结构体 PyObject,此结构体中包含3个元素。...1.3引用计数器 v1 = 3.14 v2 = 999 v3 = (1,2,3) 计数器指就是一个变量,在相同命名空间内使用次数,原本调用一次,计数1,再次被调用则计数器加1 计数器减小 当发生以下四种情况时候...以上就是引用计数器大体上机制,但是后面的缓存机制学习完之后我们才会进一步理解,这里不是简 单计数器等于0就销毁,内部还有一定缓冲,目前就简单理解成计数0,我们就进行垃圾回收。...对应[1,2,3]对象引用计数器加1,最终2....在交互模式下返回得结果符合预期,文件模式情况下 问题:为什么交互模式和命令模式结果有区别? 答:因为代码块缓存机制。 什么是代码块?

57320

Python垃圾回收机制详解「建议收藏」

一个对象有新引用时,它ob_refcnt就会增加,当引用对象被删除,它ob_refcnt就会减少。当引用计数0时,该对象生命就结束了。...无法解决循环引用问题。A和B相互引用再没有外部引用A与B中任何一个,它们引用计数都为1,但显然应该被回收。...换句话说,我们程序不再使用这些节点对象了,所以我们希望Python垃圾回收机制能够足够智能去释放这些对象并回收它们占用内存空间。但是这不可能,因为所有的引用计数都是1不是0。...在上图中,我们把小黑圈视为全局变量,也就是把它作为root object,从小黑圈出发,对象1可直达,那么它将被标记,对象2、3可间接到达也会被标记,4和5不可达,那么1、2、3就是活动对象,4和5是非活动对象会被...、中年代(第1代)、老年代(第2代),他们对应3个链表,它们垃圾收集频率与对象存活时间增大减小。

60530

深度图转换成点云

2、环境配置 开发工具QT。根据网站介绍,在进行空间坐标计算时候需要使用到一个转换矩阵Tk,而这个Tk则是需要在相机轨迹文件中提取相机轨迹文件需要使用第1步中txt文件进行解析得到。...Py_IsInitialized()) { return -1; } PyObject* pModule = PyImport_ImportModule...T[0,0]*w[0]+T[0,1]*w[1]+T[0,2]*w[2]+T[0,3]*w[3] y = T[1,0]*w[0]+T[1,1]*w[1]+T[1,2]*w[2]+T[1,3]*w...Py_IsInitialized()) { return -1; } PyObject* pModule = PyImport_ImportModule...但是这里有个疑问,每张深度图转换出点云数量是307200个,在网站上可以看到一个完整点云数量是200多万个,完整序列是2870张,所以这个数量最终无法对上,需要继续探索。

1.3K10

Python内核源码解析与CCPP-API拓展编程(二)类型对象

未完结 类型对象: 在上一篇中我们了解到了 PyObject 这个结构只有两个内容:一个引用计数, 一个类型信息....但是在现实编程过程中缺失了一些去区别python每一个类型信息,比如a=1、b=[1,2,3], 结构体引用计数1, 类型整型和list型但是没有对1 和变量名 a 、[1,2,3]和变量b表达...在上一篇中我们知道PyObject 这个结构只有两个内容:一个引用计数, 一个类型信息....似乎少了一些"内容", 比方说python代码中 a = 1 , 结构体引用计数1, 类型整型, 却没有保存 1 和变量名 a ....这样说明, PyObject 仅仅是对象共有的部分, 在使用上还需要"其他内容". 那么现在我们知道,不同于其他语言,python中整数,布尔值,字符串等类型变量均是一个对象不是简单值。

43800

Python垃圾回收机制(引用计数+标

在Python中数字是对象,字符串是对象,任何事物都是对象,它们核心就是一个结构体--PyObject。...1引用计数 通过前面的介绍,我们已经知道PyObject是每个对象必有的内容,一个对象有新引用时,它ob_refcnt就会增加,当引用对象被删除,它ob_refcnt就会减少,当引用计数...每一次赋值操作都会增加数据引用次数,要记住引用变量a、b、c指向是数据456,不是变量本身。 (3)对象作为参数传递到函数中: ? 这里可以很明显看到在被传递到函数中后,引用计数增加了1。...如下,list1与list2相互引用,如果不存在其他对象对它们引用,list1与list2引用计数也仍然1,所占用内存永远无法被回收,这将是致命。...Python将内存根据对象存活时间划分为不同集合,每个集合称为一个代,Python将内存分为了3“代”,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代),他们对应3个链表,它们垃圾收集频率与对象存活时间增大减小

78620

Python内核源码解析与CCPP-API拓展编程(一)PyObject

, 意思是说这个类型使用64位兼容方式编译, 在编译64位程序时指针就被视为64位宽, 不是32位. int也有可能会被视为64位....; 作用 表示变量引用次数, python垃圾回收机制基于引用计数, 在python运行过程中当某个对象引用计数减少到0时, 就可以将该变量从堆上删除,释放内存。...我们可以检索到引用计数处理定义。...= 0) \ ; \ else \ __Py_Dealloc((PyObject *)(op)) 引用计数0时,该对象生命周期结束...引用计数机制优点: 简单 实时性:一旦没有引用,内存就直接释放了。不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存时间分摊到了运行时。

2.1K00

Python内存管理机制

Python中有个内部跟踪变量叫做引用计数器,每个变量有多少个引用,简称引用计数。当某个对象引用计数0时,就列入了垃圾回收队列。 引用计数增加情况: 1. 一个对象分配一个新名称 2....将其放入一个容器中(如列表、元组或字典) 引用计数减少情况: 1. 使用del语句对对象别名显式销毁 2....3 垃圾回收机制 ---- 3.1 当一个对象引用计数归零时,与该对象对应析构函数就会被调用,但调用析构函数并不意味着最终一定要调用free释放内存空间,通常是将该对象通过垃圾收集机制处理,将其占用空间归还到内存池中...4 内存池机制 ---- Python提供了对内存垃圾回收机制,但是它将不用内存放到内存池不是返回给操作系统。...1. 当申请内存小于256字节时,PyObject_Malloc会在内存池中申请内存;当申请内存大于256字节时,PyObject_Malloc行为将蜕化为malloc行为。

92510

浅析 Python 一些底层原理与 CPython

这种技术允许 PyPy 在执行程序前先将部分代码编译成机器码,不是像 CPython 那样逐行解释执行。...PyObject 定义包含两个主要部分:一个引用计数器和一个对象类型指针。因此,Python 中每个对象都具有这两个属性:引用计数器和对象类型。...以列表(PyListObject 实例)例,其中 ob_size 用于维护列表元素个数。每当插入一个元素,ob_size 就会增加 1;每当删除一个元素,ob_size 就会减少 1。...这会触发一次函数调用,取出对象值进行运算,然后根据运算结果创建一个对象,并返回其对应 PyObject * 指针。...每当有新引用指向它时,refcnt 就增加 1;每当减少一个引用,refcnt 就减少 1

15900

Python源码分析(一)

引用计数   和C或C++不同,Python选择使用语言本身负责内存管理和维护,也就是垃圾收集机制,代替程序员进行繁重内存管理工作,引用计数刚好是Python垃圾收集机制一部分。   ...Python通过对一个对象引用计数来管理和维护对象在内存中存在与否。...Python中一切皆是对象,在所有的对象中有一个ob_refcent变量,维护这对象引用计数,从而也决定该对象创建与消亡。...在Python中,使用Py_INCREF(op)和Py_DECREF(op)两个宏来增加和减少一个对象引用计数,在每一个对象创建时候,Python提供了一个Py_NewReference(op)宏来将对象引用计数初始化为...当一个对象引用计数0时,与该对象对应析构函数将被调用, 但是调用析构函数并不一定是调用free释放内存空间,为了避免频繁申请、释放内存空间,Python中使用是内存对象池,维护一定大小内存对象池

92120

Python 垃圾回收机制

所以引用计数减量过程是这样一个调用链: Py_DECREF -> _Py_Dealloc -> tp_dealloc -> tp_free -> _PyObject_Free 此外,Python也提供了检查...,标记-清除和分代收集只是为了打破循环引用引入补充技术。...我们注意到这样一个事实,如果两个对象引用计数都为1,但是仅仅存在它们之间循环引用,那么这两个对象都是需要被回收,也就是说,虽然它们引用计数虽然表现为非0,但实际上有效引用计数0。...这里,我们提出了有效引用计数概念,为了从引用计数获得有效引用计数,必须将循环引用影响去除,也就是说,将环从引用中摘除,具体实现就是两个对象各自引用计数值都减去1。...,表示还没被遍历到,就设置1,表示引用关系,不可回收对象。

67320

python 内存管理与垃圾收集

也就是说 Python 内部记录着所有使用中对象各有多少引用。 当一个对象引用计数变为 0 时, 它被垃圾回收。 当对象被创建并(将其引用)赋值给变量时,该对象引用计数就被设置 1。...引用计数增加 在以下情况中,引用计数会增加: 1. 对象被创建 — x = 123 2. 另外别名被创建 — y = x 3. 作为参数被传递给函数 — foobar(x) 4....对象别名显式销毁 — del y 3. 对象一个别名被赋值其他对象 — y = ’abc’ 4. 对象被从容器中移除 — myList.remove(x) 5....容器本身销毁 — del myList 3. 垃圾收集 不再被使用内存会被垃圾收集机制释放,垃圾收集器就负责释放内存。 当对象引用计数 0 就会立即出发内存回收动作。...所有的 python 对象都由两个部分构成:PyObject_HEAD + 对象本身数据, container 对象则在其 PyObject_HEAD 前有一个 pyGC_Head,这个结构就是可收集对象链表节点结构

31910
领券