Cpython 中 PyObject 的序列化

问题描述 投票:0回答:0

我正在尝试在文件中写入一个 PyObject(以字节为单位),然后通过 Python 解释器的其他实例访问它。尽管我的主要目标是以某种方式在共享内存中包含一些 PyObjects,以便其他 python vm 实例可以访问此共享内存中的这些对象。但据我所知,共享内存(至少在 linux 中)也像文件一样工作,例如写入文件描述符和从文件描述符读取。因此,我需要将 PyObject 转换为字节,将其存储在某个文件中,并要求其他 python 解释器读取该文件。

沿着这个方向,我写了下面的函数,它接受一个 python 整数对象,将它存储在一个文件中,然后再次读取它并返回它。

PyObject* func(PyObject* self, PyObject* args)
{
    // Writing the Object to a file                                   //1
    const char* const path = "file.bin";                              //2
    FILE* file = fopen(path,"wb");                                    //3
    fwrite( args, sizeof(PyLongObject) , 1 , file );                  //4
    fclose( file );                                                   //5

    //Reading the Object from the file
    file = fopen(path,"rb");                                          //6
    PyObject* contents = NULL;                                        //7
    contents = PyMem_Malloc( sizeof(PyLongObject) );                  //8  
    fread( contents, sizeof(PyLongObject) , 1 , file );               //9
    fclose( file );                                                   //10
    
    //Forcing the REFCOUNT to 1
    Py_SET_REFCNT(contents,1);                                        //11

    return contents;                                                  //12
} 

所以如果我从模块中导入这个函数,并以整数形式给出输入,它就可以工作。这意味着它将整数 pyobject 写入文件,关闭文件,然后再次打开文件,将其内容传输到另一个 pyobject 变量,然后返回它。因此,如果我将 1 作为参数传入,则 1 将作为 pyobject 返回。

但考虑了几个小时后,我有很多疑问。

  1. 在第 4 行,如果我理解正确的话,我也在硬编码包含在这个对象中的所有指针,当我尝试从不同的 python vm 打开它时,它们将变得无用,因为所有地址都会不同.

  2. 在第 8 行,我在这里使用 PyMem_Malloc,所以我应该在该行的某处使用 free 吗?或者一旦这个“内容”对象引用计数达到 0,python vm 会调用 free 吗?

  3. 在第 11 行,我强制我的新对象的引用计数为 1,因为旧对象 (args) 引用计数也被复制到这里并且可能大于 1。这是正确的做法吗?

  4. 如果我的初始对象(args)达到引用计数 0 会发生什么?由于我已将所有指针从“args”复制到“contents”,将删除 args,同时删除“args”指向的原始对象,从而使“contents”中的指针无用。这个我试过了,如下

>>> from some_module import func
>>> a = 999999
>>> b = func(a)
>>> del(a)
>>> b
999999

“内容”变量出于某种原因仍然有效。为什么这行得通或者我的理解在两者之间的某个地方是错误的?

  1. 最后但并非最不重要的一点,做上述事情的实际正确方法是什么。也就是把python对象灭菌成文件,然后再通过文件读取。
python serialization cpython python-c-api
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.