2012-09-18 3 views
11

이것은 어리석은 질문 일 수 있지만 어쨌든 묻습니다.파이썬 생성기 개체 : __sizeof __()

>>> obj.__sizeof__() 
24 

발전기가 소비받을했다고한다 : 그것은 크기의

>>> def gen(): 
...  for i in range(10): 
...   yield i 
...   
>>> obj=gen() 

내가 측정 할 수

>>> for i in obj: 
...  print i 
...  
0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
>>> obj.__sizeof__() 
24 

...하지만 obj.__sizeof__()은 동일하게 유지 나는 발전기 개체가 있습니다. 내가 예상대로 문자열

가 작동 : 누군가가 가르치 려 수 있다면

>>> 'longstring'.__sizeof__() 
34 
>>> 'str'.__sizeof__() 
27 

내가 감사 할 것입니다.

+1

또한 ['sys.getsizeof()'(http://docs.python.org/library/sys.html#sys.getsizeof에 관심이있을 수 있습니다 예를 listiterator를 들어 해당 __length_hint__ 방법이있다). 또한 gc 오버 헤드를 고려합니다 (문제가있는 경우). 조금 덜 익숙합니다. – mhawke

+0

@mhawke : 실제로 OP는'__sizeof__'에도 관심이 없었습니다! :) –

+0

@NedBatchelder : 네, 맞아요! – mhawke

답변

23

__sizeof__() 당신이 생각하는대로하지 않습니다. 이 메서드는 생성자가 반환 할 항목 수가 아닌 지정된 객체의 내부 크기 (바이트)를 반환합니다.

파이썬은 미리 생성기의 크기를 알 수 없습니다. 예를 들어 다음 무한 생성기 (예 : 카운터를 만드는 더 좋은 방법이 있습니다)를 생각해보십시오.

def count(): 
    count = 0 
    while True: 
     yield count 
     count += 1 

해당 생성기는 끝이 없습니다. 거기에 할당 할 수있는 크기가 없습니다. 그러나 발전기 개체 자체가 메모리 취

>>> count.__sizeof__() 
88 

당신은 일반적으로 호출하지 __sizeof__() 떠날를 그 또한 가비지 컬렉터 오버 헤드를 추가 sys.getsizeof() function에.

당신은 발전기가 유한 될 것입니다을 알고 당신이 그것을 반환 얼마나 많은 항목을 알고경우, 사용 :

sum(1 for item in generator) 

하지만 참고 배출 발전기가.

+1

실제로 무한 생성기 또는 비 결정적 생성기가있을 수 있습니다 –

+0

소리가 합리 적입니다 :) 감사합니다. – root

1

__sizeof__은 생성기 길이가 아닌 바이트 단위로 개체의 메모리 크기를 반환하며, 생성기가 무한정 커질 수 있으므로 정면을 결정할 수 없습니다.

0

당신은 당신이 만든 발전기가 "유한"이라고 확신하는 경우 (요소의 셀 수 번호가) 당신은 잠시 동안 당신이 원하는 것을 얻을 다음을 사용할 수 있습니다 기다리고 괜찮다 :

len(list(gen())) 

다른 포스터와 마찬가지로 __sizeof__()은 무언가 (아마도 거의 필요하지 않은 훨씬 낮은 수준의 개념)가 아닌 얼마나 오래 기억할지를 측정 한 것입니다. 길이는 아닙니다 (발전기의 기능이 아닙니다. 셀 수있는 길이를 가짐).

6

다른 답변에서 말한 것처럼 __sizeof__은 다른 것을 반환합니다.

일부 반복자에는 반환되지 않은 요소의 수를 반환하는 메서드 만 있습니다.

>>> L = [1,2,3,4,5] 
>>> it = iter(L) 
>>> it 
<listiterator object at 0x00E65350> 
>>> it.__length_hint__() 
5 
>>> help(it.__length_hint__) 
Help on built-in function __length_hint__: 

__length_hint__(...) 
    Private method returning an estimate of len(list(it)). 

>>> it.next() 
1 
>>> it.__length_hint__() 
4 
+0

__length_hint__에 감사드립니다. len (list (it))은 반복자를 소비하지만 __length_hint__는 그렇지 않습니다. – root

+0

@root 예,'list'는 그것을 소비하고, (어떤 메모리를 사용하는) list로 변환 한 다음 생성 된리스트의 길이를 계산합니다. 'length_hint'는리스트 iterator 객체를 위해 특별히 구현 된 메소드입니다. – ovgolovin