(即。一个集合)
isinstance()
像这里建议的那样邪恶吗? http://www.canonical.org/~kragen/isinstance/
更新:我最常见的区分列表和字符串的原因是当我有一些无限深度的嵌套树/数据结构,其中有列表、列表、字符串等,我正在使用递归算法探索它们,我需要知道何时到达“叶子”节点。isinstance()
像这里建议的那样邪恶吗? http://www.canonical.org/~kragen/isinstance/
更新:我最常见的区分列表和字符串的原因是当我有一些无限深度的嵌套树/数据结构,其中有列表、列表、字符串等,我正在使用递归算法探索它们,我需要知道何时到达“叶子”节点。if type(x) is list:
print 'a list'
elif type(x) is tuple:
print 'a tuple'
else:
print 'neither a tuple or a list'
type([]) is list
返回 True
。 - David Geigertype(x) in [list,tuple]
更短。 - Alex Holcombe如果你需要的话,可以使用isinstance
。它有点邪恶,因为它会排除自定义序列、迭代器和其他你可能真正需要的东西。然而,有时候你需要根据传入的参数不同而表现出不同的行为,比如当有人传递一个字符串时。在这种情况下,我的偏好是明确地检查str
或unicode
,方法如下:
import types
isinstance(var, types.StringTypes)
注意不要将types.StringType
与types.StringTypes
混淆。后者包含str
和unicode
对象。
许多人认为,types
模块已经过时,建议直接检查对象的类型。因此,如果您不想使用上面提到的方法,可以像这样显式地检查str
和unicode
:
isinstance(var, (str, unicode)):
编辑:
更好的方法是:
isinstance(var, basestring)
编辑结束
在这两种情况下,您可以回退到像获取正常序列一样的行为,让非序列引发适当的异常。
关于类型检查的“邪恶”之处并不是你可能想要针对某种对象类型执行不同的操作,而是你人为地限制了函数处理意外对象类型时本来能够正确处理的能力。如果您有一个未经类型检查的最终回退机制,您便消除了这种限制。需要注意的是,过多的类型检查是代码异味(code smell),表明您可能需要进行一些重构,但这并不一定意味着您应该从一开始就避免使用它。
abc
模块,否则你无法使用isinstance
进行检查,即使有,我也建议尽可能避免使用检查。 - mzzisinstance
是否邪恶?”我给出了一个反例,它(1)是 isinstance
的一种非邪恶使用,因为有后备选项意味着它不会破坏鸭子类型,并且(2)对于人们想要检查是否是列表或元组(即从字符串中消除歧义)的常见动机来说,这是一个很好的解决方案。 - jcdyerisinstance(foo, (str, bytes))
。 - jcdyer只要不多余,使用 isinstance
没有问题。如果一个变量应该只是列表/元组,则记录接口并将其用作此类。否则,检查是完全合理的:
if isinstance(a, collections.abc.Iterable):
# use as a container
else:
# not a container!
这种检查确实有一些很好的用例,例如与标准字符串startswith / endswith方法一起使用(尽管要准确的说,这些方法在CPython中是用C语言实现的,使用了显式的检查来判断它是否是元组 - 正如你所链接的文章中提到的那样,解决这个问题的方法不止一种)。
直接进行检查通常比试图将对象用作容器并处理异常更好-这可能会导致代码部分或不必要地运行而导致各种问题。
set
对象也是可迭代的,这意味着你可以从中弹出元素,但它不保证特定的顺序,对于某些算法来说这是非常危险的。在元素的顺序很重要的情况下,使用此代码片段的算法可能会在不同的运行中产生不同的结果! - koocollections.Iterable
下使用,但现在已经被移动到抽象基类(abc)中,所以现在它被称为collections.abc.Iterable
。 - KyleMit将参数记录为需要是序列,并将其用作序列。不要检查类型。
在Python 2.8中,type(list) is list
返回的是false
。我建议使用这种可怕的方式进行比较:
if type(a) == type([]) :
print "variable a is a list"
(至少在我的系统上,使用Mac OS X Yosemite上的Anaconda)
type(list) is list
返回 False
,因为 type(list)
是 type
,而不是 list
。type(list()) is list
或者任何其他 列表实例 将返回 True
。 - Michael Greene>>> l = []
>>> l.__class__.__name__ in ('list', 'tuple')
True
如何理解:hasattr(a, "__iter__")
?
这段代码用来判断返回的对象是否可以被迭代,即是否可以像生成器一样遍历。默认情况下,元组和列表可以被迭代,但是字符串类型不行。
__iter__
。 - Alexander IrbisPython 使用“鸭子类型”,即如果一个变量像鸭子一样嘎嘎叫,那它就是只鸭子。在您的情况下,您可能希望它是可迭代的,或者您希望访问特定索引处的项目。您应该这样做:即在 for var:
或 var[idx]
中使用对象,并将其放在 try
块中,如果出现异常,它就不是一只鸭子...
if isinstance(x, (list, tuple))): pass
tuple
,而不是它们的 list
。 - Nicolás Ozimicadict
。这应该是被接受的答案。 - Gilles Quénot判断变量是列表还是元组,或者通常检查变量类型的另一种简单方法是:
def islist(obj):
if ("list" in str(type(obj))):
return True
else:
return False