2010-11-18 9 views
5

में मान समाप्त हो जाते हैं, मैं थ्रेड सुरक्षित पाइथन कंटेनर के बाद हूं जहां एक समय के बाद मान स्वचालित रूप से हटा दिए जाते हैं। क्या ऐसी कक्षा मौजूद है?कंटेनर जहां पाइथन

+3

संभावित डुप्लिकेट: http://stackoverflow.com/questions/3927166/automatically-expiring-variable – mouad

+0

मैं थ्रेड के बाद हूं प्रत्येक मूल्य के लिए टाइमआउट के साथ एएफ कक्षा। वह उदाहरण एक सूची और वैश्विक टाइमआउट का उपयोग करता है। – hoju

उत्तर

5

यहाँ ExpireCounter की एक धागा सुरक्षित संस्करण है:

import datetime 
import collections 
import threading 

class ExpireCounter: 
    """Tracks how many events were added in the preceding time period 
    """ 

    def __init__(self, timeout=1): 
     self.lock=threading.Lock()   
     self.timeout = timeout 
     self.events = collections.deque() 

    def add(self,item): 
     """Add event time 
     """ 
     with self.lock: 
      self.events.append(item) 
      threading.Timer(self.timeout,self.expire).start() 

    def __len__(self): 
     """Return number of active events 
     """ 
     with self.lock: 
      return len(self.events) 

    def expire(self): 
     """Remove any expired events 
     """ 
     with self.lock: 
      self.events.popleft() 

    def __str__(self): 
     with self.lock: 
      return str(self.events) 

जो इस तरह इस्तेमाल किया जा सकता:

import time 
c = ExpireCounter() 
assert(len(c) == 0) 
print(c) 
# deque([]) 

c.add(datetime.datetime.now()) 
time.sleep(0.75) 
c.add(datetime.datetime.now())  
assert(len(c) == 2) 
print(c) 
# deque([datetime.datetime(2010, 11, 19, 8, 50, 0, 91426), datetime.datetime(2010, 11, 19, 8, 50, 0, 842715)]) 

time.sleep(0.75) 
assert(len(c) == 1) 
print(c) 
# deque([datetime.datetime(2010, 11, 19, 8, 50, 0, 842715)]) 
+0

धन्यवाद! मुझे थ्रेडेड टाइमआउट पसंद है। क्या मेरा उदाहरण थ्रेड सुरक्षित नहीं था? दस्तावेज़ कहते हैं, "डेक तेजी से परमाणु परिशिष्ट() और पॉपलफ्ट() संचालन के साथ असंबद्ध कतारों का वैकल्पिक कार्यान्वयन है जिसे लॉकिंग की आवश्यकता नहीं है।" – hoju

+0

@Plumo: मैं थ्रेड सुरक्षा का निर्णय लेने में कोई विशेषज्ञ नहीं हूं, लेकिन मुझे लगता है कि ExpireCounter का आपका संस्करण थ्रेड सुरक्षित नहीं हो सकता है। 'ऐड' विधि में, 'datetime.now()' पर कॉल को तुरंत 'self.events.append' पर कॉल द्वारा नहीं किया जा सकता है। एक साथ 'add' विधि को कॉल करने वाले एकाधिक थ्रेड की कल्पना करें। 'Datetime.now' पर बहुत सी कॉल, लेकिन परिणाम एक jumbled आदेश में 'self.events' में शामिल हो जाते हैं। यदि 'self.events' को कालक्रमिक रूप से आदेश नहीं दिया गया है, तो' समाप्ति 'विधि में जबकि लूप बहुत जल्दी समाप्त हो सकता है। इस प्रकार, यह समय समाप्त होने वाले सभी तत्वों को 'पलफफ़्ट' में विफल हो सकता है। – unutbu

1

शायद आप एक एलआरयू कैश चाहते हैं। यहाँ एक मैं बाहर आज़माना चाहते है या नहीं:

http://pypi.python.org/pypi/repoze.lru

यह धागा सुरक्षित हो रहा है।

+0

एलआरयू नहीं। मैं चाहता हूं कि मेरे पास कितने मूल्य हैं और मैं उन्हें एक्सेस करता हूं, भले ही दिए गए टाइमआउट के बाद एक मूल्य समाप्त हो जाए। – hoju

+2

उस स्थिति में, आप प्रत्येक मूल्य के साथ एक समाप्ति समय स्टोर कर सकते हैं। आप किस तरह के कंटेनर अर्थशास्त्र चाहते हैं: सूची, सेट, dict, या कुछ और? –

+0

कंटेनर के प्रकार से संबंधित नहीं है जब तक कि यह धागे सुरक्षित – hoju

0

यह अब और अधिक या कम के लिए जो मैं चाहता है:

from datetime import datetime, timedelta 
from collections import deque 

class ExpireCounter: 
    """Tracks how many events were added in the preceding time period 
    """ 

    def __init__(self, timeout=timedelta(seconds=1)): 
     self.timeout = timeout 
     self.events = deque() 

    def add(self): 
     """Add event time 
     """ 
     self.events.append(datetime.now()) 

    def __len__(self): 
     """Return number of active events 
     """ 
     self.expire() 
     return len(self.events) 

    def expire(self): 
     """Remove any expired events 
     """ 
     now = datetime.now() 
     try: 
      while self.events[0] + self.timeout < now: 
       self.events.popleft() 
     except IndexError: 
      pass # no more events 


if __name__ == '__main__': 
    import time 
    c = ExpireCounter() 
    assert(len(c) == 0) 
    c.inc() 
    time.sleep(0.75) 
    c.inc() 
    assert(len(c) == 2) 
    time.sleep(0.75) 
    assert(len(c) == 1) 
संबंधित मुद्दे