首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >超载__setattr__导致AttributeError

超载__setattr__导致AttributeError
EN

Stack Overflow用户
提问于 2015-11-17 22:39:32
回答 2查看 498关注 0票数 0

我有一个类,它存储一个变量,然后当该变量更改为指定的值时,它应该能够执行作为参数传递的给定代码段。我试着这样做:

代码语言:javascript
复制
class SharedAttribute(object):    
    def __init__(self, value, onEquals={}):
        self.value = value
        self.onEquals = onEquals

    def __setattr__(self, key, val):
        super(SharedAttribute, self).__setattr__(key, val)  #Set the attribute to the new value

        if key == "value":  #If the attribute being changed is the value attribute:
            if val in self.onEquals:  #If the new value is something that should cause something to happen:
                if type(self.onEquals[val]) == str:  #If there's only one command:
                    exec(self.onEquals[val])  #execute it

                elif type(self.onEquals[val]) == tuple:  #If there's a tuple of commands:
                    for eachFunction in self.onEquals[value]:  #Execute each of them
                        exec(eachFunction)

它将被实例化如下:

代码语言:javascript
复制
foo = SharedAttribute(0, onEquals = {1: 'doSomething(arguments)', 2: ('doAnotherThing()', 'yetAnotherThing(arguments)'})

当我尝试创建类的一个实例时,它给出了

代码语言:javascript
复制
AttributeError: 'SharedAttribute' object has no attribute 'onEquals'.

我认为这是因为if val in self.onEquals在定义onEquals时试图访问onEquals,因为它调用__setattr__来定义它,但是我添加了if key == "value":,它仍然在运行。怎么了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-17 22:47:58

您的问题是,__setattr____init__中也被调用为self.value = value,然后访问未定义的self.onEquals

您可以尝试按建议更改self.valueself.onEquals行在__init__中的顺序。

但是,如果您不希望在实例化类时从onEquals运行函数,请保持原样,并检查onEquals是否已经在__setattr__中设置为:

代码语言:javascript
复制
def __setattr__(self, key, val):
    super(SharedAttribute, self).__setattr__(key, val)

    if key == "value" and getattr(self, "onEquals", False):
        ...
票数 1
EN

Stack Overflow用户

发布于 2015-11-17 22:43:14

每次访问都会调用__setattr__来保存属性。当SharedAttribute__init__()运行时,self.valueself.onEquals都不存在,但是__setattr__在设置self.value时会尝试访问self.onEquals --因为首先设置的是self.value

你有几种不同的方法来解决这个问题:

  • 交换__init__函数中的两行,或
  • 将虚拟类变量onEquals设置为空dict

第一个解决方案是最快速和最简单的;第二个解决方案有一些风险,您可能会无意中访问onEquals的类版本,然后很难找到bug。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33768460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档