Consider:
Python 2.7.3 (default, Aug 2 2012, 16:55:39)
[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import __builtin__
>>> type(iter('123'))
<type 'iterator'>
>>> type(iter('123')).__class__
<type 'type'>
>>> type(iter('123')).__name__
'iterator'
>>> type(iter('123')).__module__
'__builtin__'
>>> __builtin__.iterator
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'iterator'
>>> dir(__builtin__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']
>>>
Is it expected that __builtin__.iterator
doesn't really exist? Is there an appropriate way to obtain a reference to that class without creating a nonce-instance with iter
?
Not all internal object types are listed in the __builtin__
structure, no.
You won't find the method type there either, nor the generator type, or many others. Only names that you'd actually use in your Python code are listed in that namespace.
Some such types are listed in the types
module, but the iterator type isn't, because, as the source states:
# Iterators in Python aren't a matter of type but of protocol. A large
# and changing number of builtin types implement *some* flavor of
# iterator. Don't check the type! Use hasattr to check for both
# "__iter__" and "next" attributes instead.
If you wanted to test if something is an iterator, use the Iterator
ABC instead:
import collections
if isinstance(something, collections.Iterator):
If you have some obscure need to get the iterator
type as returned for strings, you can use type()
on it:
>>> type(iter('123'))
<type 'iterator'>
and store that; that's how the types
module produces many of its references.
However, know that that type is not universal:
>>> iterator = type(iter(''))
>>> isinstance(iter([]), iterator)
False
>>> iter([])
<listiterator object at 0x108e72d50>
>>> isinstance(reversed([]), iterator)
False
>>> reversed([])
<listreverseiterator object at 0x108e72d50>
yet testing with the ABC does recognise them all:
>>> from collections import Iterator
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter(reversed([])), Iterator)
True
>>> isinstance(iter(''), Iterator)
True
If you need to create an iterator, then either produce a sequence and return the result of iter()
on that, or produce an iterator type yourself. The latter is easy enough, either use a generator expression, use a generator function for __iter__
or give your type a __next__
method that produces an item each time it is called (and have __iter__
return self
).