我为图像缓冲区创建了一个类。该课程如下:
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
都已更改。如何使实例独立?
答案 0 :(得分:2)
ctypes.c_int
与list
一样,是可变的,不应该用作默认参数,这是一个非常常见的错误。每次调用函数时都应该创建一个新对象:
class ImgBuf():
def __init__(self, bufnr=None):
if bufnr is None:
bufnr = ctypes.c_int(-1)
self.bufnr =ctypes.c_int(bufnr)
答案 1 :(得分:1)
bufnr
之类的kwargs的默认值只会在读取def
语句时在加载时评估一次。因此,在这种情况下,c_int
将创建一次,然后相同的实例将用于所有未明确指定ImgBuf
的{{1}}个实例。
为避免这种情况,您可以使用bufnr
作为默认值,然后检查None
并在函数体内需要时实例化默认值,每次创建一个新实例时间。
这同样适用于用作默认值的任何其他可变对象,如列表,dicts等。请参阅this link。
答案 2 :(得分:-1)
请参阅以下代码剪辑:
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正确创建了类对象的两个实例,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))
现在对象应该是独立的(再次运行代码剪切)。