2014-09-01 3 views
1

고려 :__builtin __. 반복자가 존재하지 않습니다?

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'] 
>>> 

그것이 __builtin__.iterator 실제로 존재하지 않는 것으로 예상된다? iter으로 nonce-instance를 만들지 않고 해당 클래스에 대한 참조를 얻을 수있는 적절한 방법이 있습니까?

답변

3

모든 내부 개체 유형이 __builtin__ 구조에 나열되어있는 것은 아닙니다.

거기에는 메소드 유형이나 생성기 유형 또는 기타 많은 메소드가 없습니다. 파이썬 코드에서 실제로 사용하는 이름 만이 해당 네임 스페이스에 나열됩니다. 당신이 뭔가 반복자 경우 테스트하고 싶었다면

# 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. 

Iterator ABC을 대신 사용으로 source states 때문에,

일부 같은 유형의 types module에 나열되어 있지만, 반복자 타입이되지 않습니다 : 문자열을 반환 당신이 iterator 유형을 얻을 수있는 몇 가지 모호한 필요가있는 경우

import collections 

if isinstance(something, collections.Iterator): 

, 당신은 그것을 type()를 사용할 수 있습니다

>>> type(iter('123')) 
<type 'iterator'> 

및 그; 이것이 types 모듈이 많은 참조를 생성하는 방법입니다.

그러나, 그 형태가 보편적 아니라는 것을 알고

>>> iterator = type(iter('')) 
>>> isinstance(iter([]), iterator) 
False 
>>> iter([]) 
<listiterator object at 0x108e72d50> 
>>> isinstance(reversed([]), iterator) 
False 
>>> reversed([]) 
<listreverseiterator object at 0x108e72d50> 

아직 ABC는 그들 모두를 인식하지와 테스트 : 당신이 다음 반복자를 작성해야하는 경우

>>> from collections import Iterator 
>>> isinstance(iter([]), Iterator) 
True 
>>> isinstance(iter(reversed([])), Iterator) 
True 
>>> isinstance(iter(''), Iterator) 
True 

하는 중 생산합니다 시퀀스에 넣고 그 결과를 iter()으로 돌려 보내거나 직접 반복자 유형을 생성하십시오. 후자는 충분히 쉽게 생성기 식을 사용하거나 __iter__에 생성기 함수를 사용하거나 __iter__ return self을 가질 때마다 항목을 생성하는 __next__ 메서드를 입력합니다.

+0

특히 jsonpickle에'__reduce__'에 대한 지원을 추가하고 마지막 두 항목에 대해 __reduce__ 반복자를 반환한다는 PEP307 요구 사항을 고려합니다. 자신의'__reduce__ '를 사용하여 내장 iterator를 picklable로 만들 수 없으므로 중요하지 않습니다. – Marcin

+0

@Marcin :'__iter__' 메쏘드와'__next__' 메쏘드를 가진 것은 반복자이므로 특정 타입을 다시 사용할 필요가 없습니다. –

-1

그보다 더 나쁜 것은 즉시 클래스가 아닌 유형입니다.

>>> type(iter(range(5))) 
<type 'listiterator'> 

(새 스타일) 클래스 인스턴스의 유형을 묻는 경우 클래스라고합니다.

>>> class X(object): pass 
... 
>>> type(X()) 
<class '__main__.X'> 

(그리고 왜 그들이 이전 스타일 클래스에 새로운 기능을 구현하는 것이?)

은 당신이 그것의 보류를 가지고 있다면 당신이 그것으로 무엇을 할 것 감안할 때?당신이 그것을 얻을 수 있도록, 당신이 주위를 찌를 경우

확인, 어딘가에

>>> it = iter(range(5)).__class__ 

에서 클래스가하지만 당신은에서 상속 할 수 없습니다 그것을

>>> class it2(it): pass 
... 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: Error when calling the metaclass bases 
    type 'listiterator' is not an acceptable base type 

그리고 monkey- 그것을 패치하는 것은 명백하게 비열한 것으로 보인다. 뭔가가 당신을 막을 수 있기를 바랍니다.

또한 직접 인스턴스화 할 수 없습니다 :

>>> x = it() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: cannot create 'listiterator' instances 

그래서 그냥 오히려 게재하고 할 수없는 모든 정상적인 것들에 대한 사과보다, 존재하지 않는 척하는 좋은 것은 아닙니다? 동일은 기능 같은 것들에 간다

, INT, 더블STR, 적어도 당신이 그것들을 초기화 할 수 있지만, 정말 수업하지 않고, 너무 멀리가는 사람들의 대부분 유령 스럽다.

+0

인스턴스와 유형이 혼동 스럽습니다. – Marcin

+0

아니요, 아닙니다. 무엇이 당신을 그렇게 생각하도록 만들었나요? type()을 통해 인스턴스의 클래스를 얻거나 '__class__'멤버를 참조합니다. 혼란이 없습니다. –

+0

아니, 네 말이 맞아. 혼란은 사용자 정의 된 새 스타일 클래스, 기본 클래스 및 클래식 클래스 간의 차이점입니다. 클래스의 repr에 "class"라는 단어가 없거나 baseclass로 사용할 수 없다고해서 클래스가 아닌 것은 아닙니다. – Marcin

관련 문제