Python类失去了属性

jsj*_*jsj 9 python pygtk class

我有一个奇怪的python问题.在我的gtk python应用程序的执行过程中,我的一些类对象神秘地丢失属性,导致程序的某些功能中断.

很难理解为什么会发生这种情况 - 我从不故意删除属性,并且有问题的类继承自我自己编写的类(而不是其他类).

我可以通过重复执行某个操作来触发问题(例如,生成对add_card方法的多次调用- 通过疯狂点击或打开文件,导致add_card被调用20次左右)

我真的很茫然,我希望我能提供更多有用的信息给你.

什么可能导致python对象丢失属性?

编辑,回复.问题:

以下是与"失去的两个属性"相关的示例回溯:

Traceback (most recent call last):
  File "lib/genericlist.py", line 90, in cursor_changed
    if self.viewer:
AttributeError: 'DeckerRunnerList' object has no attribute 'viewer'



Traceback (most recent call last):
  File "lib/genericlist.py", line 100, in row_activated
    selection = self.TABLE_NAME+"&&"+text
AttributeError: 'DeckerRunnerList' object has no attribute 'TABLE_NAME'
Run Code Online (Sandbox Code Playgroud)

这是他们设置的地方:

class DeckerGenericList(object):   

    def __init__(self, database, viewer=None, deck=None):

        super(DeckerGenericList, self).__init__()

        self.database = database
        self.viewer = viewer
        self.deck = deck
        #TABLE_NAME is set in the subclass constructor
Run Code Online (Sandbox Code Playgroud)

这个特殊的子类不会调用它的超类,__init__因此属性集在子类中重复:

class DeckerRunnerList(DeckerGenericList):

      def __init__(self, database, viewer=None, deck=None):

        self.database = database
        self.viewer = viewer
        self.deck = deck
        self.TABLE_NAME = "runners"
Run Code Online (Sandbox Code Playgroud)

DeckerGenericList的所有其他子类都有相同的问题,它们都是这样定义的:

class DeckerGearList(DeckerGenericList):

    def __init__(self, database, viewer=None, deck=None):

        self.TABLE_NAME = "gear"
        #... some other class attributes

        super(DeckerGearList, self).__init__(database, viewer=viewer, deck=deck)
Run Code Online (Sandbox Code Playgroud)

Bun*_*nyk 2

那么您可以使用属性和检查模块来跟踪属性的更改,如下所示:

import sys
import inspect

def from_where_called():
    info = inspect.getframeinfo(sys._getframe(2))
    code = info.code_context[0] if info.code_context else ''
    return '%s:%s %s' % (info.filename, info.lineno, code)

def add_watched_attribute(name):  
    def attr_watch_get(self):
        value = getattr(self, '_' + name, 'unset')
        print from_where_called(), name, 'is', value
        return value

    def attr_watch_set(self, value):
        print from_where_called(), name, 'set to', value
        setattr(self, '_' + name, value)

    def attr_watch_delete(self):
        print from_where_called(), name, 'deleted'
        delattr(self,'_' + name)

    sys._getframe(1).f_locals[name] = property(
        attr_watch_get, attr_watch_set, attr_watch_delete
    )


class InspectedClass(object):
    add_watched_attribute('victim')

    def __init__(self):
        self.victim = 2

    def kill(self):
        del self.victim


x = InspectedClass()
x.victim = 'asdf'
x.kill()
Run Code Online (Sandbox Code Playgroud)

或者您可以使用此答案中的 sys.settrace:/sf/answers/938340651/