中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中C API如何引用計數器

發布時間:2021-10-18 15:43:37 來源:億速云 閱讀:115 作者:小新 欄目:編程語言

這篇文章給大家分享的是有關Python中C API如何引用計數器的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

簡介

Python的內存管理是通過對象的引用計數器來實現的,對象的創建會將引用計數器加1,被引用一次則引用計數器就會加1,反之解除引用時,則引用計數器就會減1,當Python對象的引用計數器為0的時候,則這個對象就會被回收和釋放。

這種內存管理的方式是有一定的弊端的,一是它需要額外的空間維護引用計數,二是它不能解決對象的“循環引用”的問題,因此,也有很多語言比如Java并沒有采用該算法做來垃圾的回收機制。

Python代碼實例

import sys

def test_refcount(a):
    print("func a refcount: {}".format(sys.getrefcount(a)))

if __name__ == '__main__':

    // 直接創建Python對象
    a = 189987319
    print("a refcount: {}".format(sys.getrefcount(a)))

    // 調用一次Python對象a,則引用計數器加1
    b = a
    print("b, a refcount: {}".format(sys.getrefcount(a)))

    // 存入列表,字段,或者元組中,引用計數器都會加1
    c = [a]
    print("c, a refcount: {}".format(sys.getrefcount(a)))

    // 使用函數調用的時候,傳參的時候引用計數器加1,調用的時候引用計數器也會加1,因此是加2
    test_refcount(a)

結果:
a refcount: 1
b, a refcount: 2
c, a refcount: 3
func a refcount: 5

Python C API中管理及釋放Python對象

void Py_INCREF(PyObject *o)  Python對象引用計數器加1,該對象不能為NULL,否則會報錯

void Py_XINCREF(PyObject *o)   Python對象引用計數器加1,該對象可以為NULL,但是引用計數器未生效

void Py_DECREF(PyObject *o)   Python對象的引用計數器減1,該對象不能為NULL,否則會報錯

void Py_XDECREF(PyObject *o)   Python對象引用計數器減1,該對象可以為NULL,但是引用計數器未生效

void Py_CLEAR(PyObject *o)  直接將Python應用計數器清0

C代碼實例

頭文件

//
// Created by lanyulei on 18-9-9.
//

#ifndef PRINT_DEMO1_PYREFCOUNT_H
#define PRINT_DEMO1_PYREFCOUNT_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Python.h>

void pyRefCount();

#endif //PRINT_DEMO1_PYREFCOUNT_H

源文件

//
// Created by lanyulei on 18-9-9.
//

#include "pyRefCount.h"

// Python對象的保留及釋放
void pyRefCount(){

    PyObject* py_ival = Py_BuildValue("i", 56486);  // 創建對象
    printf("Py_BuildValue: py_ival refcount: %ld\n", Py_REFCNT(py_ival));   // 打印Python對象的引用計數器

    Py_XINCREF(py_ival);   // Python對象的引用計數器加1
    printf("Py_BuildValue: py_ival refcount: %ld\n", Py_REFCNT(py_ival));   // 打印Python對象的引用計數器

    Py_XDECREF(py_ival);    // Python對象的引用計數器減1
    printf("Py_BuildValue: py_ival refcount: %ld\n", Py_REFCNT(py_ival));   // 打印Python對象的引用計數器

    Py_CLEAR(py_ival);   // Python對象的引用計數器清0
    printf("Py_BuildValue: py_ival refcount: %ld\n", Py_REFCNT(py_ival));   // 打印Python對象的引用計數器
}

main.cpp

#include "pyRefCount.h"

int main() {

    // 初始化Python虛擬機
    Py_Initialize();
    // 判斷Python虛擬機是否成功
    if (Py_IsInitialized() == 0){
        printf("fal to initialize Python\n");
        return -1;
    }

    printf("server start\n");
    pyRefCount();

    // 退出Python虛擬機
    Py_Finalize();
    return 0;
}

初始化Python腳本路徑

Python虛擬機在運行的時候,import一個模塊的時候,如果這個模塊沒有被加載過,則Python虛擬機就會在執行程序的所在路徑搜索這個腳本,如果找到腳本文件就將它加載,如果沒有找到,就會從sys.path中的所有路徑去搜索,如果找到腳本文件就加載,反之則報錯。

Python下的sys.path

打印所有的sys.path下的路徑

>>> import sys
>>> sys.path
['', 'C:\\WINDOWS\\SYSTEM32\\python27.zip', 'D:\\software\\Python2\\DLLs', 'D:\\software\\Python2\\lib', 'D:\\software\\Python2\\lib\\plat-win', 'D:\\software\\Python2\\lib\\lib-tk', 'D:\\software\\Python2', 'D:\\software\\Python2\\lib\\site-packages', 'D:\\software\\Python2\\Lib\\site-packages\\pytesser_v0.0.1']

將當前路徑加入到sys.path

>>> import os
>>> import sys
>>> sys.path.append(os.getcwd())
>>> sys.path
['', 'C:\\WINDOWS\\SYSTEM32\\python27.zip', 'D:\\software\\Python2\\DLLs', 'D:\\software\\Python2\\lib', 'D:\\software\\Python2\\lib\\plat-win', 'D:\\software\\Python2\\lib\\lib-tk', 'D:\\software\\Python2', 'D:\\software\\Python2\\lib\\site-packages', 'D:\\software\\Python2\\Lib\\site-packages\\pytesser_v0.0.1', 'C:\\WINDOWS\\system32']

C/C++初始化Python腳本路徑

頭文件

//
// Created by win7 on 2018/9/10.
//

#ifndef INC_20180910_PYINIT_H
#define INC_20180910_PYINIT_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Python.h>

bool initPython();

#endif //INC_20180910_PYINIT_H

源文件

//
// Created by win7 on 2018/9/10.
//

#include "pyInit.h"

bool initPython() {
    char scriptPath[128];
    sprintf(scriptPath, "sys.path.append('%s')", "./script");

    // 向Python注冊我們的腳本路徑
    PyRun_SimpleString("import sys");
    PyRun_SimpleString(scriptPath);

    PyRun_SimpleString("print sys.path");
    return true;
}

感謝各位的閱讀!關于“Python中C API如何引用計數器”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

洛宁县| 吉水县| 宜黄县| 措美县| 同仁县| 巴塘县| 漯河市| 佛冈县| 石城县| 博客| 济宁市| 河源市| 朔州市| 天等县| 沛县| 内黄县| 延川县| 敖汉旗| 龙山县| 大邑县| 新竹市| 隆尧县| 海盐县| 商城县| 射阳县| 芮城县| 顺平县| 阿克陶县| 历史| 仁布县| 紫金县| 溧水县| 务川| 砚山县| 崇仁县| 莱州市| 奈曼旗| 思南县| 永春县| 西充县| 枣强县|