假设我有一个函数f(),它接受一个列表并返回该列表的变异。如果我想将该函数应用于我的类实例(i)中的五个成员变量,我可以这样做:
for x in [i.a, i.b, i.c, i.d, i.e]:
x[:] = f(x)
1)有更优雅的方式吗?我不希望f()修改传递的列表。
2)如果我的变量包含一个简单的整数(不适用于切片表示法),还有一种方法吗? (f()也会在这种情况下采用&返回一个整数)
答案 0 :(得分:4)
另一种解决方案,虽然它可能不优雅:
for x in ['a', 'b', 'c', 'd', 'e']:
setattr(i, x, f(getattr(i, x)))
答案 1 :(得分:2)
Python没有通过引用传递。您可以做的最好的事情是编写一个构造新列表的函数,并将函数的结果分配给原始列表。例如:
def double_list(x):
return [item * 2 for item in x]
nums = [1, 2, 3, 4]
nums = double_list(nums) # now [2, 4, 6, 8]
或者更好:
nums = map(lambda x: x * 2, nums)
超级简单的例子,但你明白了。如果要从函数更改列表,则必须返回更改后的列表并将其分配给原始列表。
您可能能够破解解决方案,但最好只是以正常方式执行。
我发现我实际上并不知道你要做什么,特别是。也许如果你要澄清你的具体任务,我们可以提出一个Python允许的解决方案吗?
答案 2 :(得分:2)
最终,您想要做的是与Python的结构方式不兼容。在变量是列表的情况下,您已经拥有了最优雅的方法,但这对数字来说是不可能的。
这是因为Python中不存在变量。 参考。因此i.x
不是列表,而是对列表的引用。同样,如果它引用了一个数字。因此,如果i.x
引用y
,则i.x = z
实际上不会更改值y
,它会更改i.x
指向的内存中的位置。
大多数情况下,变量被视为包含值的框。名字在盒子上。在python中,值是基本的,“变量”只是挂在特定值上的标记。一旦你习惯它,这是非常好的。
对于列表,您可以使用切片分配,就像您已经在做的那样。这将允许对列表的所有引用查看更改,因为您正在更改列表对象本身。在数字的情况下,没有办法做到这一点,因为数字是Python中的不可变对象。这是有道理的。五是五,你可以做很多改变它。如果您知道或可以确定属性的名称,则可以使用setattr
对其进行修改,但这不会更改可能已存在的其他引用。
正如Rafe Kettler所说,如果你能更具体地了解你真正想做的事情,那么我们可以提出一种简单优雅的方式来做到这一点。