带有ctypes属性的Python类有副作用

2024-06-28 19:30:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我为图像缓冲区创建了一个类。这个班看起来像这样:

import ctypes

class ImgBuf():
    def __init__(self, bufnr=ctypes.c_int(-1)):
        self.bufnr = bufnr

属性“bufnr”通过引用传递给共享库,并更改为缓冲区管理。我想有这个类的多个实例(管理几个图像缓冲区)。在这个小例子中

import imgBuf.ImgBuf
buf1 = dicamsdk.ImgBuf()
buf2 = dicamsdk.ImgBuf()
sharedDLL.allocateBuffer(buf1)

两个实例中的bufNr都已更改。如何使实例独立?你知道吗


Tags: 实例图像importself属性initdefctypes
3条回答

在读取def语句时,像bufnr这样的Kwarg的默认值在加载时只计算一次。因此,在本例中,将创建一个c_int,然后将同一实例用于所有未显式指定bufnrImgBuf实例。你知道吗

为了避免这种情况,您可以使用None作为默认值,然后检查is None并根据需要在函数体内部实例化默认值,这样每次都会创建一个新实例。你知道吗

这同样适用于用作默认值的任何其他可变对象,如列表、dict等。见this link。你知道吗

ctypes.c_intlist一样,是可变的,不应将其用作默认参数,这是一个非常常见的错误。每次调用函数时,应创建一个新对象:

class ImgBuf():
    def __init__(self, bufnr=None):
        if bufnr is None:
            bufnr = ctypes.c_int(-1)
        self.bufnr =ctypes.c_int(bufnr)

请参见以下代码:

from imgBuf import ImgBuf
buf1 = ImgBuf()
buf2 = ImgBuf()
print('id(buf1) == id(buf2): ', id(buf1) == id(buf2))
print('id(buf1.bufnr) == id(buf2.bufnr): ', id(buf1.bufnr) == id(buf2.bufnr))

输出为

id(buf1) == id(buf2):  False
id(buf1.bufnr) == id(buf2.bufnr):  True

即使python正确地创建了class对象的两个实例,ctypes值也具有相同的标识。通常,这不是问题,因为python管理存储。但这不适用于正在使用的共享库。你知道吗

已复制默认值以确保独立实例。这个班看起来像这样:

import ctypes
from copy import copy

class ImgBuf():
    def __init__(self, bufnr=ctypes.c_int(-1)):
        self.bufnr = copy(ctypes.c_int(bufnr))

现在对象应该是独立的(再次剪掉运行代码)。你知道吗

相关问题 更多 >