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

assert isinstance(lst, (list, tuple))

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


当前回答

我倾向于这样做(如果我真的,真的必须这么做的话):

for i in some_var:
   if type(i) == type(list()):
       #do something with a list
   elif type(i) == type(tuple()):
       #do something with a tuple
   elif type(i) == type(str()):
       #here's your string

其他回答

带有PHP风格的Python:

def is_array(var):
    return isinstance(var, (list, tuple))

我在测试用例中这样做。

def assertIsIterable(self, item):
    #add types here you don't want to mistake as iterables
    if isinstance(item, basestring): 
        raise AssertionError("type %s is not iterable" % type(item))

    #Fake an iteration.
    try:
        for x in item:
            break;
    except TypeError:
        raise AssertionError("type %s is not iterable" % type(item))

没有在发电机上进行测试,我认为如果通过发电机,你会在下一次“屈服”时留下,这可能会把下游的事情搞砸。不过,这是一个unittest

简单的方法…使用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

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

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

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

仅在python2中(不是python3):

assert not isinstance(lst, basestring)

实际上是你想要的,否则你会错过很多像列表一样的东西,但不是list或tuple的子类。