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

assert isinstance(lst, (list, tuple))

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


当前回答

Python 3:

import collections.abc

if isinstance(obj, collections.abc.Sequence) and not isinstance(obj, str):
    print("`obj` is a sequence (list, tuple, etc) but not a string or a dictionary.")

在3.3版更改:将“集合抽象基类”的全局命名空间从abc移动到集合。美国广播公司(abc)模块。为了向后兼容,它们将继续在这个模块中可见,直到3.8版,它将停止工作。

Python 2:

import collections

if isinstance(obj, collections.Sequence) and not isinstance(obj, basestring):
    print "`obj` is a sequence (list, tuple, etc) but not a string or unicode or dictionary."

其他回答

我在测试用例中这样做。

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

Python 3:

import collections.abc

if isinstance(obj, collections.abc.Sequence) and not isinstance(obj, str):
    print("`obj` is a sequence (list, tuple, etc) but not a string or a dictionary.")

在3.3版更改:将“集合抽象基类”的全局命名空间从abc移动到集合。美国广播公司(abc)模块。为了向后兼容,它们将继续在这个模块中可见,直到3.8版,它将停止工作。

Python 2:

import collections

if isinstance(obj, collections.Sequence) and not isinstance(obj, basestring):
    print "`obj` is a sequence (list, tuple, etc) but not a string or unicode or dictionary."

duck-typing的另一个版本,用于帮助区分类似字符串的对象和其他类似序列的对象。

类字符串对象的字符串表示就是字符串本身,所以你可以检查你是否从str构造函数返回了一个相等的对象:

# If a string was passed, convert it to a single-element sequence
if var == str(var):
    my_list = [var]

# All other iterables
else: 
    my_list = list(var)

这应该适用于所有与str兼容的对象和所有类型的可迭代对象。

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

就这么做

if type(lst) in (list, tuple):
    # Do stuff