2012-09-18 12 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__ विधि है)। यह जीसी ओवरहेड भी मानता है (यदि यह आपके लिए मायने रखता है), और यह थोड़ा कम हैकिश है। – mhawke

+0

@mhawke: असल में, ओपी को '__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__ के लिए धन्यवाद। लेंस (सूची (यह)) एक इटरेटर का उपभोग करता है लेकिन __length_hint__ नहीं करता है। – root

+0

@root हां, 'सूची' इसे उपभोग करती है, सूची में परिवर्तित होती है (जो कुछ मेमोरी लेती है) और केवल तब बनाई गई सूची की लंबाई की गणना करती है। जबकि 'length_hint' केवल सूची इटरेटर ऑब्जेक्ट के लिए एक विशेष रूप से कार्यान्वित विधि है। – ovgolovin

संबंधित मुद्दे