访问作为可选参数传递的类实例的属性

时间:2015-02-18 10:57:23

标签: python class python-2.7 instance argument-passing

我有两个具有列表属性的类实例,例如:

foo.range = [1,2]
bar.range = [3,4]

我还有一个带有多个参数的函数:

def permutations(*args):
    return list(itertools.product(arg.range for arg in args))

我希望permutations(foo, bar)返回这两个(或更多)列表的所有排列(即[(1,3), (1,4) …]),但实际上我得到[([1, 2],), ([3, 4],)]

有人可以帮我理解我哪里出错了,以及如何达到我希望的结果?

1 个答案:

答案 0 :(得分:2)

itertools.product期望迭代可以作为单独的参数(itertools.product(*iterables[, repeat])),因此您需要使用splat( * )运算符将项目解包给它:

>>> def permutations(*args):
        return list(itertools.product(*(arg.range for arg in args)))

>>> permutations(foo, bar)
[(1, 3), (1, 4), (2, 3), (2, 4)]

考虑这个简单的函数,它将收集args中传递给它的所有位置参数:

>>> def func(*args):
    print args
    print list(args[0])
...

当我们传递一个生成器表达式时,它被收集为args元组中的一个单独项:

>>> func(x for x in range(5))
(<generator object <genexpr> at 0x7fda2ab4e780>,)
[0, 1, 2, 3, 4]

要解决这个问题,我们需要解压缩我们的生成器表达式,同样像*x for x in range(5)这样的某些东西不是Python中的有效语法,我们需要在生成器表达式周围添加额外的括号:

>>> func(*(x for x in range(5)))
(0, 1, 2, 3, 4)
# Failed as expected for args[0]
Traceback (most recent call last):
  File "<ipython-input-215-13af4340dad1>", line 1, in <module>
    func(*(x for x in range(5)))
  File "<ipython-input-213-08941e2a3c06>", line 3, in func
    print list(args[0])
TypeError: 'int' object is not iterable