>>> import Queue
>>> q = Queue.PriorityQueue()
>>> a = (1, {'item': 'value'})
>>> q.put(a)
>>> q.queue
[(1, {'item': 'value'})]
>>> a[1]['count'] = 1
>>> q.queue
[(1, {'count': 1, 'item': 'value'})]
>>> q.get()
(1, {'count': 1, 'item': 'value'})
为什么添加后更改“a”的值时队列中的值会发生变化?元组本身是不可变的,但内部的字典是可变的。但我无法理解为什么队列应该被改变?
答案 0 :(得分:2)
在Python中,对象通过引用传递。某些对象似乎可以作为值(例如字符串和整数)传递,但这是因为这些对象是不可变的(例如,您无法更改整数对象1
的值)。
因此,当您将字典放入队列时,实际字典将弹出另一端而不是副本。
如果你想要一个副本,你可以使用字典的copy()
方法,但请注意它只会给你一个浅的字典副本:副本中的键和值将是相同的对象,它们可能会自己是可变的。
答案 1 :(得分:1)
在Python中,对象既不是“通过引用”传递也不是“按值传递”。
在您的示例中,名称bool debugging = true;
Mat rgb = imread("/home/brian/qt/ANPR/images/0.jpg", 0);
if(debugging) { imshow("Original", rgb); }
Mat grad;
Mat morphKernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3));
morphologyEx(rgb, grad, MORPH_GRADIENT, morphKernel);
if(debugging) { imshow("gradient morph", grad); }
// binarize
Mat bw;
threshold(grad, bw, 0.0, 255.0, THRESH_BINARY | THRESH_OTSU);
if(debugging) { imshow("threshold", bw); }
// connect horizontally oriented regions
Mat connected;
morphKernel = getStructuringElement(MORPH_RECT, Size(10, 1));
morphologyEx(bw, connected, MORPH_CLOSE, morphKernel);
if(debugging) { imshow("horizontal regions morph", connected); }
// find contours
Mat mask = Mat::zeros(bw.size(), CV_8UC1);
vector<vector<Point> > contours2;
vector<Vec4i> hierarchy;
vector<Rect> txtRect;
vector<vector<Point> > txtContour;
findContours(connected, contours2, hierarchy, CV_RETR_CCOMP,
CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
// filter contours
for(int i = 0; i >= 0; i = hierarchy[i][0]) {
Rect rect = boundingRect(contours2[i]);
Mat maskROI(mask, rect);
maskROI = Scalar(0, 0, 0);
// fill the contour
drawContours(mask, contours2, i, Scalar(255, 255, 255), CV_FILLED);
// ratio of non-zero pixels in the filled region
double r = (double)countNonZero(maskROI)/(rect.width*rect.height);
/* assume at least 45% of the area is filled if it contains text */
if (r > .45 && (rect.height > 10 && rect.width > 10)) {
rectangle(rgb, rect, Scalar(0, 255, 0), 2);
txtRect.push_back(rect);
txtContour.push_back(contours2[i]);
}
}
if(debugging) { imshow("Characters", rgb); }
Mat text(rgb.size(), CV_8U, Scalar(255));
drawContours(text, txtContour, -1, Scalar(0), FILLED, 4);
if(debugging) { imshow("Detected Text", text); }
绑定到对象a
。
名称(1, {'item': 'value'})
绑定到队列对象。
当调用q
时,名称q.put(a)
绑定的对象“放入”名称a
绑定的对象,以便名称{{ 1}}和q
指的是同一个对象。因此,当您修改该对象时,您正在修改绑定a
和q[0]
的对象(因为它们绑定到同一个对象)。
其次,尽管元组是不可变的,但这并不意味着它不能改变。虽然作为“容器”它是不可变的并且本身不能改变,但它可以包含可变对象,因此它的内容可以改变。
这里非常有用和明确的文章: https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/