为了明确扩展Alex Martelli的出色技巧collections.py并解决围绕它的一些问题:python 3.6+中当前有效的解决方案是
import collections
import _collections_abc as cabc
import abc
class NonStringIterable(metaclass=abc.ABCMeta):
__slots__ = ()
@abc.abstractmethod
def __iter__(self):
while False:
yield None
@classmethod
def __subclasshook__(cls, c):
if cls is NonStringIterable:
if issubclass(c, str):
return False
return cabc._check_methods(c, "__iter__")
return NotImplemented
并展示
>>> typs = ['string', iter(''), list(), dict(), tuple(), set()]
>>> [isinstance(o, NonStringIterable) for o in typs]
[False, True, True, True, True, True]
iter('')例如,如果要添加到排除项中,请修改该行
if issubclass(c, str):
return False
成为
if issubclass(c, (str, cabc.str_iterator)):
return False
要得到
[False, False, True, True, True, True]