Python类丢失属性 [英] Python classes losing attributes

查看:165
本文介绍了Python类丢失属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个特殊的python问题。在我的gtk python应用程序的执行过程中,我的一些类对象神秘地失去了属性,导致我的程序的一些功能破裂。

I have a peculiar python problem. During the course of execution of my gtk python application, some of my class objects mysteriously lose attributes, causing some of the functionality of my program to break.

很难给一个感觉为什么这可能发生 - 我从来没有故意删除属性,有关的类继承自我写的自己(而没有其他人)。

It's hard to give a sense of why this might happen - I never intentionally delete attributes, and the classes in question inherit from a class I wrote myself (and no others).

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

I can trigger the problem by doing a certain action repeatedly (for example generating many calls to the add_card method - either by clicking madly or by opening a file, causing add_card to be called twenty or so times)

我真的很失落,我希望我有更多的信息,我认为有用的给你。

I am really at a loss, and I wish I had more information I thought useful to give you.

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

What can cause a python object to lose attributes?

问题:

这里是与我失去的两个属性相关的示例跟踪:

Here are example tracebacks related to the two attributes I 'lose':

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'

这里是它们的设置:

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

这个特殊的子类不会调用它的超类 __ init __ ,所以属性集在子类中重复:

This particular subclass doesen't call it's superclass __init__ so the attribute sets are duplicated in the subclass:

class DeckerRunnerList(DeckerGenericList):

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

        self.database = database
        self.viewer = viewer
        self.deck = deck
        self.TABLE_NAME = "runners"

DeckerGenericList的所有其他子类都有相同的问题,它们都定义如下:

All the other subclasses of DeckerGenericList have the same issue, and they are all defined like this:

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)


推荐答案

PyQT(因此也许还有PyGtk或其他框架)实际上在属性代码内部/下面产生AttributeError的行为实际上会使得该对象的被调用属性不存在的python报告。

PyQT (and therefore maybe also PyGtk or other framework) has the weird behaviour that actually raising an AttributeError somewhere within/below the attribute code will actually make python report that the called attribute on that object does not exist.

有一个官方)故事某处为什么这是(并且是实际正确和可理解的行为)。它与在基类上定义的__getattr__有关:它的作用的meganism是,如果调用对象上的属性导致一个AttributeError,__getattr__方法被调用。但是这种方法不知道什么'属性'实际上没有找到。并且由于(PyQt.QObject)__getattr__被设计为实现特定属性,它决定引发另一个AttributeError提到被调用属性。

There is a (somewhat more official) story somewhere about why this is (and is actually right and understandable behaviour). It has something to do with __getattr__ being defined on a base class: The meganism by which that works is that if calling the attribute on an object results in an AttributeError, the __getattr__ method is called. But that method has no idea what 'attribute' was actually not found. And since the (PyQt.QObject) __getattr__ was designed to implement 'specific' attributes, it decides to raise another AttributeError mentioning the 'called' attribute.

无论如何,可以是继承自一个使用__getattr__的对象,并且你自己的属性代码调用(另一个)属性,存在。您可以执行以下操作来检查:

Anyway, what could be is that you are inheriting from an object which uses __getattr__ somewhere and that your own attribute code does call (another) attribute which does, indeed, not exist. What you can do to check this is:

@property
def myproperty:
   try:
      doStuff..
   except AttributeError as e:
      print "Got ya! It is withing the attribute:", repr(e)
      raise ValueError("Got an AttributeError within my attribute!")

更新/注意:如果你在DeckerGenericList对象上实现__getattr__,与此同样的原因!在__getattr__内部提高AttributeError的大部分时间会导致看起来像这样奇怪的行为。注意,没有简单的修复:realAttributeError只包含一个字符串消息(而不是具体的实际属性名称),但更重要的是:__getattr__函数从不会看到原始的AttributeError。

Update/Note: Also, if you are implementing __getattr__ yourself on your DeckerGenericList object, be carefull with it for this very same reason! Raising AttributeError's within __getattr__ will most of the time lead to seemingly weird behaviour like this. Note that there is no easy fix: The 'real' AttributeError only carries a string message (and not specificly the actual attribute name), but much more important: the __getattr__ function never sees the original AttributeError in the first place.

这篇关于Python类丢失属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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