我们如何测试X是否像列表/元组一样嘎嘎作响?
我的意思是我们可以用0和1(等)来对它进行子集化,尽管它不能是一个字符串(它也可以是子集)。
我想要测试hasattr(X, '__iter__')
和not isinstance(X, str)
,但这意味着字典仍会通过我不想要的字典。然后你也可以测试它不是字典,但我不会那么确定dicts的子类等。
在这个简单的规范下,是否有更正式的方法来测试某些东西是否像列表或元组一样嘎嘎作响?
E.g。允许的输入应该是:
'emailaddr' --> ('emailaddr', 'emailaddr')
('emailaddr', 'alias')
['emailaddr', 'alias']
SequenceThing('emailaddr', 'alias')
答案 0 :(得分:2)
您想检查某个值是否为sequence?
一个iterable,它通过 getitem ()特殊方法使用整数索引支持有效的元素访问,并定义一个返回序列长度的 len ()方法。一些内置序列类型是list,str,tuple和bytes。请注意,dict还支持 getitem ()和 len (),但它被认为是映射而不是序列,因为查找使用任意不可变键而不是整数。
旧方法(在2.7中弃用):
import operator
print operator.isSequenceType(x)
新方式:
import collections
print isinstance(x, collections.Sequence)
它们不相同 - 后者更准确,但自定义类型需要registered。
此外,字符串是根据两种定义的序列。您可能希望特别对待basestring
。
答案 1 :(得分:2)
不要允许裸字符串作为参数;这是一个等待咬你的特殊情况。相反,记录输入必须是元组/列表/等等的形式,但第二个元素是可选的。也就是说,
['emailaddr', ]
('emailaddr', )
SequenceThing('emailaddr')
是合法的,但不是
'emailaddr'
这样,您的函数可以假定X[0]
将是一个电子邮件地址,并且X[1]
可能存在并且是别名,但如果用户提供其他内容则是用户的问题。
答案 2 :(得分:1)
鸭子打字意味着你只是想要你想做,如果它不起作用,这意味着你没有处理鸭子。
如果您特别不想获取字符串,请检查字符串并引发异常。
然后做任何你想做的事情,不进行类型检查。
答案 3 :(得分:0)
基于Kevin的有用评论的解决方案:
>>> import collections
>>> isinstance([], collections.Sequence) and not isinstance([], str)
True
>>> isinstance((), collections.Sequence) and not isinstance((), str)
True
>>> isinstance('', collections.Sequence) and not isinstance('', str)
False
>>> isinstance({}, collections.Sequence) and not isinstance({}, str)
False
>>> isinstance(set(), collections.Sequence) and not isinstance(set(), str)
False
dicts和sets等映射不会通过第一次测试。字符串会,但在第二次测试中显然会失败。