Python中使用getattr/setattr访问列表项

9

尝试使用Python中的getattr和setattr函数访问/分配列表中的项目。不幸的是,似乎没有办法将列表索引位置与列表名称一起传递。
以下是我的一些尝试和示例代码:

class Lists (object):
  def __init__(self):
    self.thelist = [0,0,0]

Ls = Lists()

# trying this only gives 't' as the second argument.  Python error results.
# Interesting that you can slice a string to in the getattr/setattr functions
# Here one could access 'thelist' with with [0:7]
print getattr(Ls, 'thelist'[0])


# tried these two as well to no avail.  
# No error message ensues but the list isn't altered. 
# Instead a new variable is created Ls.'' - printed them out to show they now exist.
setattr(Lists, 'thelist[0]', 3)
setattr(Lists, 'thelist\[0\]', 3)
print Ls.thelist
print getattr(Ls, 'thelist[0]')
print getattr(Ls, 'thelist\[0\]')

请注意,在attr函数的第二个参数中,您不能在此函数中连接字符串和整数。

祝好


1
@BrainStorm的回答是正确的,但这通常让人感觉你的方法不对。你最终想要实现什么? - lambacck
这到底是怎么回事...?列表中的项目不是列表的属性,所以显然这样做不会起作用。 - kindall
真正想做什么? - Karl Knechtel
1
@insomniaccanuck,我们知道你在这个例子中试图做什么,但是有一个更大的问题驱使你尝试这些。也许你正在尝试将分层查询字符串解析为嵌套对象/列表,或者你想要一个配置项,让你从配置项唯一地遍历嵌套对象层次结构,或者你正在尝试做其他事情,但是关于更大的画面的更多信息将帮助我们指导你找到解决方案。 - lambacck
1
好的,再多读一些并思考后,我认为最好的方法是使用嵌套列表的字典。 函数setattr没有我需要的功能(可能有很好的原因)。 我试图构建一个n维集合,并对其进行置换群操作。我来自组合数学背景,还没有那么多计算机科学术语。学习Python(和编程)是为了找工作。 感谢大家。 - insomniaccanuck
显示剩余2条评论
3个回答

9
getattr(Ls, 'thelist')[0] = 2
getattr(Ls, 'thelist').append(3)
print getattr(Ls, 'thelist')[0]

如果你想要像 getattr(Ls, 'thelist[0]') 这样做,你需要重写 __getattr__ 或使用内置的 eval 函数。


好的,这只是其中一部分。谢谢。 我以为我已经尝试过setattr和getattr了,但我想我只尝试过setattr。 它会产生这个错误: setattr(Ls,'thelist',3)[2] TypeError:'NoneType'对象不可订阅 - insomniaccanuck
getattr(Ls, 'thelist') 返回 thelist 属性,它是一个列表。对返回的结果进行任何你想要的操作。 'NoneType' object is not subscriptable 这意味着当你调用 thelist 时,它是 None,而不是 [](列表)。首先要初始化它。 - warvariuc

5

您可以这样做:

l = getattr(Ls, 'thelist')
l[0] = 2  # for example
l.append("bar")
l is getattr(Ls, 'thelist')  # True
# so, no need to setattr, Ls.thelist is l and will thus be changed by ops on l
< p > getattr(Ls,'thelist') 能够为您提供一个与 Ls.thelist 相同的列表引用。


感谢您提供这个可行的解决方法,但它不太适用于大规模操作。也就是说,您必须重新分配整个列表。我只想从列表中分配/调用一个项目。 - insomniaccanuck
1
不需要执行 setattr(Ls, 'thelist',l)。Ls.thelist 和 l 是同一个列表,因此在这种情况下设置 l[0] 等同于 Ls.thelist[0]=2 - lambacck
@lambacck,我不这么认为...但我没有测试过,所以我可能是错的。 - BrainStorm
2
最终结果是一样的,但BrainStorm的方法允许您通过字符串数据进行赋值。而你的方法是直接按名称赋值,这并不能解决我的问题。 - insomniaccanuck
1
@BrainStorm:请查看关于“对象传递”的这篇文章 - lambacck
1
Ls.thelist 是 getattr(Ls, 'thelist'),所以,是的,setattr 这一行不需要。我想我会进行编辑以删除它。 - Skylar Saveland

3

正如您发现的那样,__getattr__不能这样使用。如果您真的想使用列表索引,请使用__getitem____setitem__,并忘记getattr()setattr()。像这样:

class Lists (object):

    def __init__(self):
        self.thelist = [0,0,0]

    def __getitem__(self, index):
        return self.thelist[index]

    def __setitem__(self, index, value):
        self.thelist[index] = value

    def __repr__(self):
        return repr(self.thelist)

Ls = Lists()
print Ls
print Ls[1]
Ls[2] = 9
print Ls
print Ls[2]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接