是否有更好的(即更多Pythonic)方式来处理打包/解包函数参数?

时间:2016-07-02 00:40:56

标签: python python-2.7 argument-unpacking

我正在编写一种方法来“添加滴答”到一个对象。 (“添加刻度”的含义对我的问题无关紧要。您也可以忽略我的代码示例中的“批处理”变量。)所有刻度将具有相同的宽度和长度,但是处于不同的刻度位置,并且每次调用可以是可变数量的刻度。目前我的方法如下:

    def addTicks(self, batch, (w,l), *ticks):
        for tick in ticks:
             # create Tick at location tick with width 'w' and length 'l'

当我这样称呼它时,这很好用:

self.addTicks(self.tickBatch, (3,10), 5, 15, 25, 35, 45, 55)

但是当我想在从0到59的所有整数位置添加刻度时,我不想输出所有数字。目前我称之为:

self.addTicks(self.tickBatch, (2,7), *[i for i in range(0,60)])

即。我创建一个范围,通过列表解析将其转换为列表,然后在调用时解压缩该列表,以便该方法可以接收它作为元组打包。它有效,但看起来有些混乱,并且可能会让其他人阅读代码时感到困惑。

我的问题是:

  1. 经验丰富的Python程序员会像我一样偶然发现这种结构吗?
  2. 有没有更好的方法来达到同样的效果?
  3. 我应该更改方法的签名吗?我知道我可以用*ticks替换tickList,但是每当我调用它时,我都必须将刻度值括在一个列表中,这对我来说似乎更吵。
  4. (这适用于Python 2.7)

    编辑:用户奇特给了我*范围(0,60)有效的答案。 我可以看到它有效,但现在我意识到我不知道如何描述它。我们“解压缩了迭代器”,但这给了我们什么?它不是一个列表,它不是一个元组。我们只是说“迭代器的元素吗?(我可以编程Python好吧,我只是说不出来了。)

    编辑:好的,我已切换到一个列表(并停止解压缩我的宽度,长度对),我的方法现在看起来像这样

    def addTicks(self, batch, tickDimensions, ticks):
    

    这意味着我现在称之为:

    self.addTicks(self.tickBatch, (2,7), range(0,60))
    self.addTicks(self.tickBatch, (3,10), [15, 25, 35, 45, 55, 5])
    

    我最初的直觉是在列表范围之外创建一个列表,但我想Pythonic认为range和列表一样可以迭代,所以我们可以直接传递它? / p>

1 个答案:

答案 0 :(得分:2)

我会选择(3)并从一开始就将刻度存储在一个列表中。在我看来,您需要输入的额外[]不是一个大问题,从Zen of Python的角度来看,列表会有一些优势:

  • 接收列表的函数比可变函数简单。
  • 如果使用列表而不是可变参数,则更明确的是刻度线是一个序列。
  • 如果您使用列表,则只有一种明显的方法可以将标记传递给您的函数。另一方面,如果你使用varargs,事情就不那么明显了(因为这个问题的存在表明了这一点)。

另一种考虑的可能性是通过将addTicks函数更改为您在循环内调用的addTick函数来完全避免此问题。 (这可能是也可能不是一个好主意,取决于你的功能如何实际工作)