Python中CAPI如何引用計(jì)數(shù)器-創(chuàng)新互聯(lián)

這篇文章給大家分享的是有關(guān)Python中C API如何引用計(jì)數(shù)器的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的四方臺(tái)網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

簡(jiǎn)介

Python的內(nèi)存管理是通過(guò)對(duì)象的引用計(jì)數(shù)器來(lái)實(shí)現(xiàn)的,對(duì)象的創(chuàng)建會(huì)將引用計(jì)數(shù)器加1,被引用一次則引用計(jì)數(shù)器就會(huì)加1,反之解除引用時(shí),則引用計(jì)數(shù)器就會(huì)減1,當(dāng)Python對(duì)象的引用計(jì)數(shù)器為0的時(shí)候,則這個(gè)對(duì)象就會(huì)被回收和釋放。

這種內(nèi)存管理的方式是有一定的弊端的,一是它需要額外的空間維護(hù)引用計(jì)數(shù),二是它不能解決對(duì)象的“循環(huán)引用”的問(wèn)題,因此,也有很多語(yǔ)言比如Java并沒(méi)有采用該算法做來(lái)垃圾的回收機(jī)制。

Python代碼實(shí)例

import sys

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

if __name__ == '__main__':

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

    // 調(diào)用一次Python對(duì)象a,則引用計(jì)數(shù)器加1
    b = a
    print("b, a refcount: {}".format(sys.getrefcount(a)))

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

    // 使用函數(shù)調(diào)用的時(shí)候,傳參的時(shí)候引用計(jì)數(shù)器加1,調(diào)用的時(shí)候引用計(jì)數(shù)器也會(huì)加1,因此是加2
    test_refcount(a)

結(jié)果:
a refcount: 1
b, a refcount: 2
c, a refcount: 3
func a refcount: 5

Python C API中管理及釋放Python對(duì)象

void Py_INCREF(PyObject *o)  Python對(duì)象引用計(jì)數(shù)器加1,該對(duì)象不能為NULL,否則會(huì)報(bào)錯(cuò)

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

void Py_DECREF(PyObject *o)  Python對(duì)象的引用計(jì)數(shù)器減1,該對(duì)象不能為NULL,否則會(huì)報(bào)錯(cuò)

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

void Py_CLEAR(PyObject *o)  直接將Python應(yīng)用計(jì)數(shù)器清0

C代碼實(shí)例

頭文件

//
// 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對(duì)象的保留及釋放
void pyRefCount(){

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

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

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

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

main.cpp

#include "pyRefCount.h"

int main() {

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

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

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

初始化Python腳本路徑

Python虛擬機(jī)在運(yùn)行的時(shí)候,import一個(gè)模塊的時(shí)候,如果這個(gè)模塊沒(méi)有被加載過(guò),則Python虛擬機(jī)就會(huì)在執(zhí)行程序的所在路徑搜索這個(gè)腳本,如果找到腳本文件就將它加載,如果沒(méi)有找到,就會(huì)從sys.path中的所有路徑去搜索,如果找到腳本文件就加載,反之則報(bào)錯(cuò)。

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']

將當(dāng)前路徑加入到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注冊(cè)我們的腳本路徑
    PyRun_SimpleString("import sys");
    PyRun_SimpleString(scriptPath);

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

感謝各位的閱讀!關(guān)于“Python中C API如何引用計(jì)數(shù)器”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

文章名稱:Python中CAPI如何引用計(jì)數(shù)器-創(chuàng)新互聯(lián)
路徑分享:http://muchs.cn/article44/cspjhe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開(kāi)發(fā)企業(yè)建站、品牌網(wǎng)站制作、標(biāo)簽優(yōu)化、定制網(wǎng)站、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)