关于python:在实例对象之间无意中共享了一个私有列表变量

A private list variable is inadvertently shared between instance objects

我创建了许多PlotHandler类的实例。实例必须使其变量保持私有。但是我管理它们的方式导致了一个难以检测的问题,一个私有列表变量在实例之间共享!也没有任何明显的泄漏源。

我的调试告诉我,修改列表的私有成员函数可以看到相同的列表,即使它们是不同的对象。

这是一个"明白"的问题吗?解决此问题的最佳方法是什么?

以下是相关部分(希望是!)执行情况。请参见所有大写注释:

实现plothandler的文件:

1
2
3
4
5
6
7
8
9
10
11
class PlotHandler(wx.Frame):
    __crop_section = None
    __projection   = None
    __crop_xcord   = None

    _band_data     = [] #THIS GETS SHARED

def _on_plot_click(self, xcord): #CALLED BY ANOTHER OBJECT
    band = self._analyze_band( xcord )
    self._band_data.append(band)
    ...

它正在管理Plothandlers的父类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MainFrame(wx.Frame):
    __close_callback__ = None
    _plot_handlers     = []
    def __init__(self, parent, title):
        ...


    def InitUI(self):
        ...

        img_handler = ImageHandler(panel)
        self.img_src.register_callback( img_handler.update_image )

        #you need to call PlotHandler(parent, cropped)
        img_handler.register_sample_callback( self._create_new_plot_handler )

        ...

    def _create_new_plot_handler(self, cropped_sample ):
    self._plot_handlers.append( PlotHandler(self, cropped_sample) ) #CREATE THEM


查看这个问题,这个问题,以及通过谷歌搜索"python class variableshared"、"python faq class variables"等可以找到的大量其他内容。

简短的回答是:直接在类体中定义的变量是类变量,而不是实例变量,因此在类的实例之间共享。如果需要实例变量,必须在方法中分配它们,在方法中可以访问self


类属性在实例之间共享。如果要定义实例属性(这样每个对象都有自己对变量的引用),则必须在__init__中定义它。

1
2
3
4
5
6
7
class PlotHandler(wx.Frame):
    __crop_section = None
    __projection   = None
    __crop_xcord   = None

    def __init__(self, **kwargs):
        self._band_data = [] #THIS IS NOT SHARED