我想清理一些我写过的代码,以便扩展我想要做的事情.为了做到这一点,我想理想地创建一个对象的引用列表,这样我就可以使用循环系统地设置对象,而不必将对象放在列表中.我已经阅读了Python处理引用和传递的方式,但还没有找到一种方法来有效地执行此操作.
为了更好地展示我正在尝试做的事情:
我正在使用散景,并希望设置大量的选择框.每个框都是这样的
select_one_name = Select(
title = 'test',
value = 'first_value',
optiOns= ['first_value', 'second_value', 'etc']
)
设置每个选择都很好,当我只有几个时,但是当我有20个时,我的代码变得非常长而且笨重.我希望能够做的,是有一个列表sample_list = [select_one_name, select_two_name, etc]
是然后依次通过,设置每个值我可以select_one_name
,select_two_name
等等.但是,我想有我引用select_one_name
仍然指向正确的值,而不是必须通过调用来引用该值sample_list[0]
.
我不确定这是否可行 - 如果有更好的方法可以做到这一点,而不是创建一个参考列表,请告诉我.我知道我可以创建一个对象列表,但我试图避免这种情况.
作为参考,我使用的是Python 2.7,Anaconda发行版,Windows 7.谢谢!
关注@Alex Martelli的帖子如下:
我认为这可能不起作用的原因是因为当我尝试使用列表列表进行小型测试时,我没有得到我想要的结果.展示
x = [1, 2, 3]
y = [4, 5, 6]
test = [x, y]
test[0].append(1)
结果,x = [1, 2, 3, 1]
但如果相反,我使用test[0] = [1, 2]
,然后x
仍然[1, 2, 3]
,虽然test
本身反映了变化.
回到我原来的例子,我想我会看到相同的结果,从设置到相等.这不是真的吗?
1> Alex Martell..:
每个Python list
总是内部是一个引用数组(在CPython中,毫无疑问你正在使用它,在C级别它是一个数组PyObject*
- "Python对象的指针").
没有隐式地创建对象的副本:而是(再次,在CPython中)当您将"对象"(实际上是对它的引用)添加到列表时,每个对象的引用计数都会增加.事实上,当你想要一个对象的副本时,你需要特别要求一个(copy
通常使用模块,或者有时使用特定于类型的复制方法).
对同一对象的多个引用是指向完全相同内存的内部指针.如果一个对象是可变的,那么对它进行变异会通过对它的所有引用进行反映.当然,有不可变的对象(字符串,数字,元组,......),这种变异不适用于这些对象.
所以,当你这样做时,例如,
sample_list = [select_one_name, select_two_name, etc]
每个名称(只要它在范围内)仍然引用与其中相应项目完全相同的对象sample_list
.
换句话说,只要存在对同一对象的两个引用,使用sample_list[0]
和select_one_name
完全等效.
IOW平方,你声明的目的已经完成了Python最基本的语义.现在,请编辑Q以澄清您正在观察哪种行为似乎与此相矛盾,以及您认为应该观察(和期望)的行为,并且我们可能能够进一步提供帮助 - 因为在这一点上所有上面的观察数量相当于"你得到了你所要求的语义",所以"随着时间的推移"是"我可以实际建议的!" - )
添加(在答案中更好,而不是在下面的评论中:-):注意改变操作的重点.OP test[0]= somelist
随后尝试test[0].append
并且看到相应的somelist
变异; 然后尝试test[0] = [1, 2]
,并惊讶地看到somelist
没有改变.但那是因为对引用的赋值不是对象的变异操作,所述引用用于指示!它只是re-seats
引用,递减先前引用的对象的引用计数,就是这样.
如果你想改变一个现有的对象(首先需要一个可变的对象,但是,list
满足那个),你需要对它进行变异操作(通过任何引用,无关紧要).例如,除了append
和许多其他命名方法之外,列表上的一个变异操作是分配给切片,包括表示为的整个列表切片[:]
.所以,test[0][:] = [1,2]
实际上会发生变异somelist
- 很不同,test[0] = [1,2]
其中分配给一个参考,不是一个切片.