2012-01-31 4 views
2

generator (__iter__)가 list()로 호출되는지 여부를 감지하는 방법이 있습니까? 내가 이해하는대로 list (obj)는 __iter__이라고 부를 것이다. 그러나 무한 생성기의 경우 오류를 반환해야합니다.생성자의 __iter__이 list()로 호출되는지 여부를 감지합니다.

예를 들어, 나는 다음과 발전기 있습니다

def gen(): 
    while 1: 
     yield 1 

목록 (세대)를 호출하기 때문에 무한 루프가 발생합니다을, 나는 그것이 오류를 반환 있도록 만들고 싶어. 이것을 할 수있는 방법이 있습니까?

+1

, 그리고 돈 'list()'의 책임이라고 생각하지 않습니다. 그것은 프로그래머의 책임입니다! – wim

+0

누구와 함께 이것을 보호하려고합니까? 무한한 발전기의 이름을 적절히 지정하면 발전기에 대한 호출을 작성하는 사람이 누구인지 분명해야합니다. 예 : 'list (allPrimeNumbers()) '라고 쓰면받을 자격이 있습니다. –

답변

4

을 수행하는 합리적인 방법은 없습니다. stacktrace를 납치 할 수는 있지만 추악하고 오류가 발생하기 쉽습니다.

가 (물론, 당신이 뭘하려는 건지 반복 가능이 그것을 할 수없는 또 다른 좋은 이유는 파이썬, 행동 것으로 예상되는 어떻게하지.)

게다가, 루프 영원히하지 않습니다, 계속해서 목록에 대한 메모리를 할당하려고합니다. 이 작업이 실패하면 즉시 MemoryError이 처리되고 인터프리터가 복구 될 수도 안될 수도 있습니다. 그렇지 I가 무엇을 요구 동안

+0

감사합니다. 별도의'next'와'__iter__' 속성을 가진 커스텀 타입을 해킹 할 수 있습니다. – Hypercube

+0

좋습니다. 내 대답을 보라. – Hypercube

+0

기본적으로 말한 것을 확장하지 않았습니까? –

2

내가 여기에 들어 가지 못하는 끔찍한 흑 마술없이. docstring에 "이것은 전부가 아닙니다."라고 적어주십시오. 그리고 목록에 전화하지 않는 것을 기억하십시오.

0

, 여기에 같은 일을 기본적으로 수행하는 솔루션입니다 :이을 보장하기 위해`__iter__`의 책임없는

class test: 
    def __init__(self): 
     self.generate = self.gen() 
     self.next = self.generate.next 
    def gen(self): 
     for a in range(10): 
      yield a 
    def __iter__(self): 
     raise ValueError 
 
>>> a = test() 
>>> a.next() 
0 
>>> list(a) 
ValueError: 
관련 문제