問題描述
我可以檢查 next()
方法,但這是否足夠?有沒有意識形態的方式?
I can check for a next()
method, but is that enough? Is there an ideomatic way?
推薦答案
在 Python 2.6 或更高版本中,用于此類行為檢查的內置習慣用法是在 collections<中使用抽象基類的成員檢查"/code> 標準庫模塊:
In Python 2.6 or better, the designed-in idiom for such behavioral checks is a "membership check" with the abstract base class in the collections
module of the standard library:
>>> import collections
>>> isinstance('ciao', collections.Iterable)
True
>>> isinstance(23, collections.Iterable)
False
>>> isinstance(xrange(23), collections.Iterable)
True
確實,這種檢查是新抽象基類的主要設計原因(第二個重要的原因是在某些情況下提供混合功能",這就是為什么它們是 ABC 而不僅僅是接口 - 但是不適用于 collections.Iterable
,它存在 嚴格 以允許使用 isinstance
或 issubclass
進行此類檢查).ABC 允許實際上不從它們繼承的類被注冊"為子類,以便此類檢查可以成為 ABC 的子類";并且,它們可以在內部對特殊方法(在本例中為 __iter__
)執行所有需要的檢查,因此您不必這樣做.
Indeed, this kind of checks is the prime design reason for the new abstract base classes (a second important one is to provide "mixin functionality" in some cases, which is why they're ABCs rather than just interfaces -- but that doesn't apply to collections.Iterable
, it exists strictly to allow such checks with isinstance
or issubclass
). ABCs allow classes that don't actually inherit from them to be "registered" as subclasses anyway, so that such classes can be "subclasses" of the ABC for such checks; and, they can internally perform all needed checks for special methods (__iter__
in this case), so you don't have to.
如果您被舊版本的 Python 卡住了,請求寬恕比請求許可要好":
If you're stuck with older releases of Python, "it's better to ask forgiveness than permission":
def isiterable(x):
try: iter(x)
except TypeError: return False
else: return True
但這不像新方法那樣快速和簡潔.
but that's not as fast and concise as the new approach.
請注意,對于這種特殊情況,您通常需要特殊情況的字符串(它們是可迭代的,但大多數應用程序上下文都希望將其視為標量").無論您使用哪種方法來檢查可迭代性,如果您需要這種特殊的大小寫,只需預先檢查 isinstance(x, basestring)
- 例如:
Note that for this special case you'll often want to special-case strings (which are iterable but most application contexts want to treat as "scalars" anyway). Whatever approach you're using to check iterableness, if you need such special casing just prepend a check for isinstance(x, basestring)
-- for example:
def reallyiterable(x):
return not isinstance(x, basestring) and isinstance(x, collections.Iterable)
編輯:正如評論中指出的那樣,問題集中在對象是否是迭代器***而不是它是否可迭代***(所有迭代器是可迭代的,但反之亦然——并非所有可迭代對象都是迭代器).isinstance(x, collections.Iterator)
是專門檢查該條件的完全類似的方法.
Edit: as pointed out in a comment, the question focuses on whether an object is an iter***ator*** rather than whether it's iter***able*** (all iterators are iterable, but not vice versa -- not all iterables are iterators). isinstance(x, collections.Iterator)
is the perfectly analogous way to check for that condition specifically.
這篇關于如何檢查一個對象是否是 Python 中的迭代器?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!