【问题标题】:Check if input is a list/tuple of strings or a single string检查输入是字符串列表/元组还是单个字符串
【发布时间】:2010-10-29 16:42:35
【问题描述】:

我有一个方法,我希望它能够接受单个字符串(路径,但不一定存在于运行代码的机器上)或字符串列表/元组。

鉴于字符串充当字符列表,我如何判断该方法接收到的是哪种类型?

我希望能够接受单个条目的标准或 unicode 字符串,以及多个列表或元组,因此 isinstance 似乎不是答案,除非我错过了一个聪明的技巧(比如利用共同的祖先类?)。

Python 版本是 2.5

【问题讨论】:

标签: python typechecking python-2.5


【解决方案1】:

您可以检查变量是字符串还是 unicode 字符串

  • Python 3:
    isinstance(some_object, str)
  • Python 2:
    isinstance(some_object, basestring)

这将为字符串和 unicode 字符串返回 True

当您使用 python 2.5 时,您可以执行以下操作:

if isinstance(some_object, basestring):
    ...
elif all(isinstance(item, basestring) for item in some_object): # check iterable for stringness of all items. Will raise TypeError if some_object is not iterable
    ...
else:
    raise TypeError # or something along that line

严格性可能不是一个词,但我希望你明白

【讨论】:

  • 啊哈!我以为在某个地方一定有一些共同的祖先,我只是找不到参考...
  • python 3 已删除 basestring。改用str(或bytes,如果你有字节......)
  • 使用six库,您可以使用six.string_types代替strbasestring以获得兼容性。
  • isinstancetype 由于性能原因,应避免在生产中使用。应该改用鸭子打字。
【解决方案2】:

isinstance 一个选项:

In [2]: isinstance("a", str)
Out[2]: True

In [3]: isinstance([], str)
Out[3]: False

In [4]: isinstance([], list)
Out[4]: True

In [5]: isinstance("", list)
Out[5]: False

【讨论】:

    【解决方案3】:

    类型检查:

    def func(arg):
        if not isinstance(arg, (list, tuple)):
            arg = [arg]
        # process
    
    func('abc')
    func(['abc', '123'])
    

    可变参数:

    def func(*arg):
        # process
    
    func('abc')
    func('abc', '123')
    func(*['abc', '123'])
    

    【讨论】:

      【解决方案4】:

      因为我喜欢保持简单,这里是与 2.x 和 3.x 兼容的最短形式:

      # trick for py2/3 compatibility
      if 'basestring' not in globals():
         basestring = str
      
      v = "xx"
      
      if isinstance(v, basestring):
         print("is string")
      

      【讨论】:

        【解决方案5】:
        >>> type('abc') is str
        True
        >>> type(['abc']) is str
        False
        

        此代码与 Python 2 和 3 兼容

        【讨论】:

        • 似乎是迄今为止最简洁明了的方式。
        • 对于 python2,这将丢失 unicode 字符串,这就是为什么 python2 示例使用basestring。例如type(u'abc') is str -> False
        【解决方案6】:

        用 isinstance(arg, basestring) 检查类型

        【讨论】:

          【解决方案7】:

          我很惊讶没有人给出鸭子类型的答案,而是给出了不清楚或高度依赖于类型或版本的答案。此外,不幸的是,接受的答案对于 Python 2 和 3 有单独的代码。Python 使用并鼓励鸭子类型,所以(比 sorin 的“最短形式”多一行,不是鸭子类型)我建议:

          def is_str(v):
              return hasattr(v, 'lower')
          

          ...以及您要使用的任何其他属性(记住引号)。这样,使用您的软件的客户端代码可以发送他们想要的任何类型的字符串,只要它具有您的软件所需的接口。 Duck 类型以这种方式对其他类型更有用,但通常是最好的方式。

          或者您也可以这样做(或通常检查 AttributeError 并采取其他措施):

          def is_str(v):
              try:
                  vL = v.lower()
              except AttributeError:
                  return False
              return True
          

          【讨论】:

          • 但是如果你正在编写一个is_str 函数,那真的是鸭子打字吗?我想,但如果你需要使用.lower(),那么只需使用.lower() 并抓住潜在的AttributeError。无需先浪费循环检查。问题是,有时您没有调用任何特定的字符串方法。例如。也许您将字符串直接传递给另一个函数。在理想情况下,that 函数会为非字符串引发异常,但您不能总是指望它。有时,isinstance() 确实是理想的解决方案。
          • @DominickPastore 是的,您不会使用我的功能(但这是一个示例并直接回答了问题)。在它之前我说“或者你可以......”并不是说使用该功能是鸭子打字。正如您所说,这就是将我的函数主体(或执行您所说的或我在函数之前所说的)内联和围绕它形成代码。我不同意isinstance--鸭子类型的要点以及 Python 使用它的原因是当对象执行您想做的事情时不会出错,而是处理个别异常--如果它“像鸭子一样嘎嘎叫”,那就是一只鸭子(或者你可以指望它的用例)。
          • 注意我说的是“把我的函数体”内联,而不是定义。您只需使用其中的代码而不是定义它,然后您将修改代码以执行特定于您的代码的事情,而不是函数的作用。
          【解决方案8】:

          你考虑过varargs 语法吗?我不确定这是否是您要问的问题,但您会喜欢this question 这样的内容吗?

          【讨论】:

          • 这不是强制调用者指定要发送的内容吗?如果可能的话,我宁愿避免这种情况。 (而且我也很好奇我想做的事情是否可以以一种优雅的方式实现......)
          【解决方案9】:

          你不能这样做:

          (i == list (i) or i == tuple (i))
          

          如果输入是元组或列表,它会回复。唯一的问题是它不适用于只包含一个变量的元组。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-22
            • 2019-04-08
            • 2013-01-09
            • 1970-01-01
            • 1970-01-01
            • 2017-12-04
            相关资源
            最近更新 更多