【问题标题】:Python class instance not being destroyed at end of method [duplicate]Python类实例在方法结束时没有被销毁[重复]
【发布时间】:2015-04-12 10:45:20
【问题描述】:

首先我应该说这是在 IPython 中运行的,如果有什么不同,请使用 Spyder IDE。我是 Python 的新手,但精通其他语言。

我有一个在函数中实例化和使用的类,如下所示。我已经从一个很长的读取和处理算法中简化了代码。当我第一次运行这个文件并调用 ReadFile() 时,这一切都很好。任何后续运行都会崩溃,主要是因为 m_seclist 和 m_headers 已经包含数据。

我对类的理解来自 C++、PHP 和 VB,所以我可能不同意我的假设,但是由于类是在函数(即本地范围)内实例化的,所以实例是否应该在结束时不被完全销毁功能?在这种情况下,它似乎非常肯定不是,或者至少一些变量仍然存在。我是否误解了 Python 如何处理类实例?

class Reader:
    m_headers = []
    m_seclist = []


    def __init__(self, filename):
        fh = open(filename, 'r')
        file_contents = fh.read().splitlines()
        fh.close()

        dataPointList = []

        for line in file_contents:
            for each section in the file (more code here)
                thisLine = line.split()
                dataPointList.append((float(thisLine[1]), float(thisLine[0])))
            m_seclist.append(dataPointList)
            dataPointList = []

    def getData(self, index):
        return m_seclist[index][0]

  #end of class
   def ReadFile(filename):
       my_instance = Reader(filename)
       output = my_instance.getData(2)
       return output

如果我能澄清一些事情,请大喊。

【问题讨论】:

  • 您能否澄清一下您是如何注意到“一些变量仍然存在”的?
  • 您的其余代码在哪里?我没有看到任何对象启动。
  • 本质上 ReadFile 函数在第二次运行时崩溃(即在第一次运行后直接运行),在调试时我打印了 m_seclist 列表以发现它们包含数据的两个副本(例如 1 ,2,3,1,2,3 应该是 1,2,3)
  • @kasperTaeymans 我认为它的 my_instance = Reader(filename) 行,这不是初始化类的正确方法吗?

标签: python class garbage-collection ipython spyder


【解决方案1】:

你的问题是你存储数据的方式:

类属性存储在类中,并在类的所有实例之间共享。

相反,实例属性按实例计数。

代替

class Reader:
    m_headers = []
    m_seclist = []


    def __init__(self, filename):

class Reader:
    def __init__(self, filename):
        self.m_headers = []
        self.m_seclist = []
        ...

然后它们在每个实例中都是新的和新鲜的。

【讨论】:

  • 如何让某样东西成为实例属性而不是共享?
  • @TomKilney read the docs?
  • 谢谢,我会的。我不能说我遇到过类变量有用的情况,但大概存在这种情况!
  • @Tom 他们肯定存在。
  • 你有例子吗(我很好奇)
【解决方案2】:

您误解了类和实例成员。你用这个做什么:

class Reader:
    m_headers = []
    m_seclist = []

是声明类成员。他们活了下来。

你想要的是这个,哦,python 中的约定只是在 _ 私有成员前面加上前缀。我还添加了 with 语句,它是处理需要关闭的资源的首选。

class Reader:

    def __init__(self, filename):
        self._headers = [] # This creates instance members
        self._seclist = []
        with open(filename, 'r') as fh: # With statement will auto close fh
            file_contents = fh.read().splitlines()

        for line in file_contents:
            dataPointList = []
            for each section in the file (more code here)
                thisLine = line.split()
                dataPointList.append((float(thisLine[1]), float(thisLine[0])))
            self._seclist.append(dataPointList)

    def getData(self, index):
        return self._seclist[index][0]

def ReadFile(filename):
    my_instance = Reader(filename)
    output = my_instance.getData(2)
    return output

【讨论】:

  • 为什么是_?我认为这里没有必要......
  • 我刚刚将他的私有成员变量约定 m_varname 翻译成 Python 的 self._varname
猜你喜欢
  • 1970-01-01
  • 2016-12-24
  • 1970-01-01
  • 1970-01-01
  • 2013-07-06
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多