如何找出 Python 对象丢失属性的原因/时间? [英] How can I find out why/when a Python object loses attributes?

查看:74
本文介绍了如何找出 Python 对象丢失属性的原因/时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新 2013-02-08

我现在知道为什么我无法在一小段测试代码中重现这个问题.在一个小程序中,Python 的垃圾收集器不是很活跃.我认为问题在于 Python 正在收集一些仅在 GObject 中引用的对象.我认为这是涉及此错误的回归,或新的类似错误.

I have an idea now why I haven't been able to reproduce this problem in a small piece of test code. In a small program, Python's garbage collector isn't very active. I believe the problem is that Python is collecting some objects that are only referenced in GObject. I think it's a regression involving this bug, or a new similar bug.

我想通了,因为我再次遇到了同样的问题,但是使用我自己的类(它只具有来自 GObject 对象的引用)——这次整个 dict 在对象上被抹去了.如果我使用代码这里来监控消失的属性之一,它不会消失!似乎额外的参考保留了属性.这闻起来像是垃圾收集器的问题.我通过让对象在初始化期间将自身添加到全局列表中来确认这一点......这也解决了现在发生的问题.

I figured this out because I encountered the same problem again, but with my own class (which has references only from GObject objects) -- this time the entire dict is getting wiped out on the object. Uf I use the code here to monitor one of the attributes that dissappears, it doesn't disappear! It seems the extra reference keeps the attributes around. That smells like a garbage collector problem. I confirmed this by having the object add itself to a global list during initialization... that also fixes the problem as it occurs now.

我在使用 PyGTK GUI 时遇到了一些奇怪的行为.我有一个始终丢失大量属性的对象.我正在尝试确定这是否是我的代码、Python 解释器或 PyGTK 中的错误.

I am experiencing some bizarre behavior with a PyGTK GUI. I have an object which is consistently losing a large number of attributes. I am trying to determine if this is a bug in my code, the Python interpreter, or PyGTK.

我不调用 delattr().我尝试通过使用总是引发异常的代码覆盖 __delattr__() 来检测是否有任何东西正在调用我的对象的 __delattr__() 方法.我能够重现导致对象失去其属性的事件,但从未引发异常.我不确定是否有其他方法可以找出导致对象丢失属性的函数调用(如果有).

I make no calls to delattr(). I have tried detecting if anything is calling the __delattr__() method of my object by overriding __delattr__() with code that always raises an exception. I am able to reproduce the event which causes the object to lose its attributes but the exception is never raised. I'm not sure of another way to find out what function calls (if any) are causing the object to lose attributes.

有问题的对象在任何时候都运行良好,直到它突然丢失我试图访问的属性.

The object in question is working perfectly at all times up until it suddenly loses attributes I'm trying to access.

在 GUI 中执行一些与丢失属性的对象无关的操作后,属性丢失始终发生.我偶然发现了它;可能还有其他动作导致对象失去其属性.

The attribute loss occurs consistently after performing some actions in the GUI that have nothing to do with the object that is losing attributes. I discovered it by accident; there may be other actions that cause the object to lose its attributes.

我已将 print id(self) 添加到访问消失属性的方法中.属性消失前后打印的id是一样的.

I have added print id(self) to the method which access the disappearing attribute. The id that is printed is the same before and after the attribute disappears.

关于如何追踪这个问题的根源有什么建议吗?

Any suggestions on how to track down the source of this problem?

下面的参考代码: (注意:如果/当我提出一个重现问题的简化测试用例时,我将更新此代码.现在重现问题所需的总代码错误太大,无法在此处发布.)

这是我的对象失去其属性的类.这显然是真实功能代码的最小化版本,但我用它来调试,问题仍然存在.

Here is the class for my object which loses its attributes. This is obviously a minimized version of the real functional code, but I am using this for debugging and the problem still occurs.

它是我的自定义 MenuBar 类的子类.请注意,on_file_import__activate() 方法通过父类之一连接到菜单项的信号.

It is a subclass of my custom MenuBar class. Note that the on_file_import__activate() method is connected to the signal for the menu item by one of the parent classes.

class FluidClassManagerWindowMenu(MenuBar):
    menu_items = [("File",("Import",))]

    def __init__(self, parent):
        # XXX: different name than self.parent to see if it stops disappearing 
        self._xxx_my_parent = parent
        MenuBar.__init__(self, parent)

    def __delattr__(self,attr):
        # XXX: trying to find the cause for lost attributes
        traceback.print_stack()

    def on_file_import__activate(self, widget=None, data=None):
        # XXX: this is the same before and after the attributes disappear
        print id(self)
        # XXX: print the list of attributes to see what disappears
        print dir(self)
        # XXX: this works until the _xxx_my_parent attribute disappears
        print self._xxx_my_parent

如果您好奇,这里是我的 MenuBar 类的完整源代码.它是一个 pygtkhelpers SlaveView,它继承自 GObject.pygtkhelpers 委托对上述 on_file_import__activate 方法进行自动信号连接.

If you're curious, here is the complete source for my MenuBar class. It is a pygtkhelpers SlaveView, which inherits from GObject. The pygtkhelpers delegate does the automagic signal connection to the on_file_import__activate method above.

class MenuBar(pygtkhelpers.delegates.SlaveView):        
    def __init__(self, parent):
        SlaveView.__init__(self)
        self.parent = parent

    def create_ui(self):
        menu_bar = gtk.MenuBar()
        menu_bar.set_pack_direction(gtk.PACK_DIRECTION_LTR)

        for menu_name, items in self.menu_items:
            menu = gtk.Menu()
            submenu = gtk.MenuItem(menu_name)
            submenu.set_submenu(menu)
            for item_name in items:
                if not item_name:
                    menu.append(gtk.MenuItem())
                    continue
                menuitem = gtk.MenuItem(item_name)
                fixed_item_name = item_name.lower().replace(' ','_')
                fixed_menu_name = menu_name.lower().replace(' ','_')
                attr_name = '%s_%s' % (fixed_menu_name,fixed_item_name)
                # set an attribute like self.edit_vial_layout
                # so pygtkhelpers can find the widget to connect the signal from
                setattr(self,attr_name,menuitem)
                menu.append(menuitem)
            menu_bar.append(submenu)
        self.vbox = gtk.VBox()
        self.vbox.pack_start(menu_bar)
        self.vbox.show_all()
        self.widget.add(self.vbox)

从对象中消失的属性列表:

'_model', '_props', '_toplevel', '_xxx_my_parent', 'file_import', 'parent', 'slaves', 'testtesttest', 'vbox', 'widget'

属性 parent 是原来消失的东西;我尝试将其值分配给 _xxx_my_parentManagerWindowMenu.__init__() 但它也消失了.我还在 MenuBar.__init__ 中添加了一个我从未访问过的新属性,称为 testtesttest,它也消失了.

The attribute parent is what originally was disappearing; I tried assigning its value to _xxx_my_parent in ManagerWindowMenu.__init__() but it disappears as well. I also added a new attribute in MenuBar.__init__ that I never access, called testtesttest, and it disappears too.

推荐答案

我遇到了一个非常相似的问题.我有一个类 (SearchWorker),它构建了一个小部件,用于在运行时添加到 GUI.在那个小部件中,有一个按钮,其点击"信号连接到 SearchWorker 函数之一.每当点击"信号被触发时,SearchWorker self 对象的许多属性都消失了.

I had a very similar problem. I had a class (SearchWorker) that built a widget for adding to the GUI at runtime. In that widget, there was a button whose "clicked" signal was connected to one of the SearchWorker functions. Whenever the "clicked" signal was fired, many of the attributes of the SearchWorker self object were gone.

我在不同类的另一个处理程序中创建 SearchWorker 对象,如下所示:

I was creating the SearchWorker object in another handler of a different class like this:

worker = SearchWorker()

我认为,一旦该处理程序退出,worker 引用后面的对象就会发生一些奇怪的事情.将 SearchWorker 的创建更改为:

I presume that once that handler exited something odd happened to the object behind the worker reference. Changing the creation of SearchWorker to:

self.worker = SearchWorker()

解决了我的问题.

这篇关于如何找出 Python 对象丢失属性的原因/时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆