AttributeError:无法在python中设置属性


70

这是我的代码

N = namedtuple("N", ['ind', 'set', 'v'])
def solve()
    items=[]
    stack=[]
    R = set(range(0,8))
    for i in range(0,8):
        items.append(N(i,R,8))      
        stack.append(N(0,R-set(range(0,1)),i))
    while(len(stack)>0): 
        node = stack.pop()
        print node
        print items[node.ind]   
        items[node.ind].v = node.v

在最后一行中,我无法将items[node.ind].v值设置为所需的值node.v,并且出现错误

"AttributeError: can't set attribute"

我不知道出什么问题了,但是它一定是基于语法的,因为使用语句node.v+=1也显示相同的错误。我是Python的新手,所以请提出一种使上述更改成为可能的方法。


感谢您的回答,但是在进行类似比较的情况下items[i].v <8,我只是尝试使用一个临时变量来存储其值,然后像temp = items[i].vthen那样使用它进行比较temp<8
Pratyush Dhanuka 2014年

有没有必要时采取特殊措施访问一个namedtuple的属性。
伊格纳西奥·巴斯克斯

访问没有问题,但是我不能重新分配它,而且我理解这和我不能使用它进行比较的相同原因,就像我提到的那样items[i].v]<8。我需要知道其他更好的选择,例如使用的答案._replace()
Pratyush Dhanuka 2014年

在表达式中使用它不需要替换它。
伊格纳西奥·巴斯克斯

是的,它起作用了,不知道为什么我在之前的声明中出错:C
Pratyush Dhanuka 2014年

Answers:


67
items[node.ind] = items[node.ind]._replace(v=node.v)

(注意:不要因为函数_replace中的下划线而使用此解决方案。特别是对于namedtuple,某些函数具有下划线,但这并不是要表明它们是“私有”)


15
为什么?⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀–
luckydonald


22
@ IgnacioVazquez-Abrams在此答案中需要更多说明。(链接到文档还不够。)
dbliss

2
@kroiz Dennis表示我们使用下划线表示方法和属性,以将其与字段名称区分开,jonrsharpe给出了详细的答案,但我的问题是要找到纠正错误的最佳方法,使用内置功能总是更好。提到那部分。.坦率地说,我本来会接受的,但堆栈不允许这样做
Pratyush Dhanuka

7
TLDR;这是一个有效的解决方案。函数_replace中的下划线不表示内部用法。
kroiz

65

namedtuple就像标准元组一样,s是不可变的。您有两种选择:

  1. 使用不同的数据结构,例如,一个类(或仅一个字典);要么
  2. 代替更新结构,而是替换它。

前者看起来像:

class N(object):

    def __init__(self, ind, set, v):
        self.ind = ind
        self.set = set
        self.v = v

后者:

item = items[node.ind]
items[node.ind] = N(item.ind, item.set, node.v)

编辑:如果需要后者,则Ignacio的答案使用内置功能可以更巧妙地完成相同的操作。


是的,经过10分钟后,我按照您在后者中所说的做了,现在我明白了为什么这样做了,但是我以前在做什么。Thnx
Pratyush Dhanuka 2014年

2
namedtuple是不可变的-击中钉子。谢谢
Tinkerbell '18

7

对于那些搜索此错误的人,可以触发的另一件事AtributeError: can't set attribute是,如果您尝试设置@property没有设置方法的装饰。这不是OP的问题,但我将其放在此处可帮助任何直接搜索错误消息的问题。(如果您不喜欢它,请编辑问题的标题:)

class Test:
    def __init__(self):
        self._attr = "original value"
        # This will trigger an error...
        self.attr = "new value"
    @property
    def attr(self):
        return self._attr

Test()

小注:为了使它在Python 2中起作用,您需要制作Test一个“新式”类,即显式派生自object(第一行必须读为class Test(object):。另请参见stackoverflow.com/a/45062077/1753435
andreee
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.