这是我通常所做的,以确定输入是一个列表/元组-而不是一个str。因为很多次我偶然发现错误,其中一个函数错误地传递了一个str对象,而目标函数在lst中执行x,假设lst实际上是一个列表或元组。

assert isinstance(lst, (list, tuple))

我的问题是:有没有更好的方法来实现这个目标?


当前回答

Python 3有这个:

from typing import List

def isit(value):
    return isinstance(value, List)

isit([1, 2, 3])  # True
isit("test")  # False
isit({"Hello": "Mars"})  # False
isit((1, 2))  # False

因此,要检查list和tuple,它将是:

from typing import List, Tuple

def isit(value):
    return isinstance(value, List) or isinstance(value, Tuple)

其他回答

一般来说,迭代对象的函数不仅适用于元组和列表,也适用于字符串,这是一个特性而不是缺陷。您当然可以使用isinstance或duck类型来检查参数,但为什么要这样做呢?

这听起来像是一个反问句,但事实并非如此。“为什么我要检查参数的类型?”这个问题的答案很可能是针对实际问题的解决方案,而不是感知到的问题。为什么将字符串传递给函数是一个bug ?另外:如果将字符串传递给这个函数是一个bug,那么如果将其他一些非列表/元组可迭代对象传递给它也是一个bug吗?为什么,或者为什么不?

我认为这个问题最常见的答案可能是,编写f(“abc”)的开发人员希望函数的行为就像他们编写的f([“abc”])一样。在某些情况下,保护开发人员不受自己的伤害比支持在字符串中遍历字符的用例更有意义。但我会先好好想想。

简单的方法…使用any和isinstance

>>> console_routers = 'x'
>>> any([isinstance(console_routers, list), isinstance(console_routers, tuple)])
False
>>>
>>> console_routers = ('x',)
>>> any([isinstance(console_routers, list), isinstance(console_routers, tuple)])
True
>>> console_routers = list('x',)
>>> any([isinstance(console_routers, list), isinstance(console_routers, tuple)])
True

Python 3有这个:

from typing import List

def isit(value):
    return isinstance(value, List)

isit([1, 2, 3])  # True
isit("test")  # False
isit({"Hello": "Mars"})  # False
isit((1, 2))  # False

因此,要检查list和tuple,它将是:

from typing import List, Tuple

def isit(value):
    return isinstance(value, List) or isinstance(value, Tuple)

我在tensorflow中找到了这样一个名为is_sequence的函数。

def is_sequence(seq):
  """Returns a true if its input is a collections.Sequence (except strings).
  Args:
    seq: an input sequence.
  Returns:
    True if the sequence is a not a string and is a collections.Sequence.
  """
  return (isinstance(seq, collections.Sequence)
and not isinstance(seq, six.string_types))

我已经核实了,它符合你的需求。

assert (type(lst) == list) | (type(lst) == tuple), "Not a valid lst type, cannot be string"