【问题标题】:how to unpack a tuple that MAY contain a list如何解压可能包含列表的元组
【发布时间】:2012-11-19 16:10:25
【问题描述】:

我在尝试将 sqlite 查询传递给另一个函数时遇到问题。

问题是 sqlite 查询可能包含一个列表,因此我不能使用*args,因为它解包元组但随后忽略了列表,我试图传递给函数的示例查询:

'SELECT postname FROM history WHERE postname = ? COLLATE NOCASE', [u'Test']

所以在这种情况下,我可以在目标函数中使用 args 而不是 *args,但是我可能有一个不包含列表的 sqlite 查询,因此我不能总是这样做,例如

'SELECT * FROM history' 

所以简而言之,我想我的问题是如何使用 args 成功地将 sqlite 查询传递给另一个函数,无论它是否包含列表?

【问题讨论】:

  • 我认为最好的答案(如果可能的话)是确保你总是得到一个元组。请记住,您可以获得长度为 1 的元组 - ("SELECT * FROM histroy", ) 可以完美运行。
  • @Lattyware -- 为什么不把它作为答案发布呢?我不知道 sqlite,否则我可能会对此有所贡献,但如果你说的是正确的,它似乎确实比我的解决方案更好。
  • 嗨 Lattyware,我已经尝试过您的解决方案,但是 sqlite 无法使用元组,我收到错误 ValueError: operation parameter must be str or unicode,因此我回到了我无法解压缩元组的问题当我松开列表时。
  • 我并不是建议您将元组传递给函数,而是建议您始终解包参数,并将任何不是元组的参数设为长度为 1 的元组。

标签: python sqlite list tuples


【解决方案1】:

你可以try,except吗?

try:
   func(*args)
except TypeError:
   func(args)

当然,这也会在你的函数中捕获TypeErrors。因此,您可能想要创建另一个函数来实际处理解包并确保给您一个可解包的对象作为回报。这也不适用于字符串,因为它们也会解包(参见 cmets)。

这是一个确保对象可以被解包的函数。

def unpackable(obj):
    if hasattr(obj,'__iter__'):
       return obj
    else:
       return (obj,)

func(*unpackable(args))

【讨论】:

  • 如果单个项目是字符串,这将不起作用(或至少不是预期的那样),因为字符串将被解包。 (参见 3.x 上的 print(*"test")from __future__ import print_function)。
  • grumbles -- @Lattyware,它会做一些事情,但它可能不正确。如果我想不出一个干净的解决方法,我会在一分钟内删除...
【解决方案2】:

我认为最好的答案是尝试并确保您始终放入一个可迭代对象,而不是尝试处理具有单个项目的奇怪情况。

如果您在一个地方有('SELECT postname FROM history WHERE postname = ? COLLATE NOCASE', [u'Test']),则传递长度为一的元组更有意义 - ('SELECT * FROM history', ) 而不是字符串。

您还没有说字符串的来源,因此您可能根本无法更改数据的方式,但如果可以,元组是从代码中删除边缘情况的更好选择.

如果你真的不能这样做,那么你想要解压任何非字符串迭代,检查可以如this question所示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-14
    • 2014-08-26
    • 1970-01-01
    • 2021-10-04
    • 2015-03-04
    • 2021-10-28
    • 2018-04-08
    相关资源
    最近更新 更多