Автоматически истекающая переменная - PullRequest
4 голосов
/ 13 октября 2010

Как реализовать автоматически истекающую переменную в Python?Например, пусть программа работает в течение одного часа.Я хочу реализовать массив из 6 переменных, каждая переменная в массиве будет автоматически удалена сама через 10 минут.И через 1 час в массиве не будет переменной.

Ответы [ 6 ]

7 голосов
/ 13 октября 2010

Я действительно должен был сделать это для словарей.Может быть, вы найдете код полезным:

"""Cache which has data that expires after a given period of time."""
from datetime import datetime, timedelta

class KeyExpiredError(KeyError): pass 

def __hax():
    class NoArg: pass
    return NoArg()
NoArg = __hax()

class DataCache(object):
    def __init__(self, defaultExpireTime=timedelta(1, 0, 0), dbg=True):
        self.defaultExpireTime = defaultExpireTime

        self.cache = {}
        self.dbg = dbg

        self.processExpires = True

    def setProcessExpires(self, b):
        self.processExpires = b

    def __getitem__(self, key):
        c = self.cache[key]

        n = datetime.now()
        if (n - c['timestamp']) < c['expireTime'] or not self.processExpires:
            return c['data']

        del self.cache[key]

        if self.dbg:
            print "DataCache: Key %s expired" % repr(key)

        raise KeyExpiredError(key)

    def __contains__(self, key):
        try:
            self[key]
            return True
        except KeyError:
            return False

    def __setitem__(self, key, val):
        self.cache[key] = {
            'data': val,
            'timestamp': datetime.now(),
            'expireTime': self.defaultExpireTime,
            }

    def items(self):
        keys = list(self.cache)
        for k in keys:
            try:
                val = self[k]
                yield (k, val)                                             
            except:
                pass

    def get(self, key, default=NoArg, expired=NoArg):
        try:
            return self[key]
        except KeyExpiredError:
            if expired is NoArg and default is not NoArg:
                return default
            if expired is NoArg: return None
            return expired
        except KeyError:
            if default is NoArg: return None
            return default

    def set(self, key, val, expireTime=None):
        if expireTime is None:
            expireTime = self.defaultExpireTime

        self.cache[key] = {
            'data': val,
            'timestamp': datetime.now(),
            'expireTime': expireTime,
            }

    def tryremove(self, key):
        if key in self.cache:
            del self.cache[key]
            return True
        return False

    #the following you can call without triggering any expirations
    def getTotalExpireTime(self, key):
        """Get the total amount of time the key will be in the cache for"""
        c = self.cache[key]
        return c['expireTime']

    def getExpirationTime(self, key):
        """Return the datetime when the given key will expire"""
        c = self.cache[key]
        return c['timestamp'] + c['expireTime']

    def getTimeRemaining(self, key):
        """Get the time left until the item will expire"""
        return self.getExpirationTime(key) - datetime.now()

    def getTimestamp(self, key):
        return self.cache[key]['timestamp']

    def __len__(self):
        return len(self.cache)

Использование:

>>> dc = DataCache(timedelta(0, 5, 0)) #expire in 5 seconds
>>> dc[4] = 3
>>> dc[4]
3
>>> import time
>>> time.sleep(5)
>>> dc[4]
DataCache: Key 4 expired
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    dc[4]
  File "datacache.py", line 35, in __getitem__
    raise KeyExpiredError(key)
KeyExpiredError: 4
>>> 
7 голосов
/ 13 октября 2010

Хммм, кажется странным, но возможно.

Похоже, вам нужен класс, который записывает время, когда вызывается __init__. Затем внедрите __getitem__, чтобы проверить время, когда он вызывается, и верните элемент, только если еще не слишком поздно. (Вероятно, это проще сделать, чем запустить процесс «в фоновом режиме», который активно удаляет элементы, даже если вы их не просите.)

1 голос
/ 14 октября 2010
import sched
import time
import threading

a = [1, 2, 3, 4, 5, 6]

scheduler = sched.scheduler(time.time, time.sleep)

def delete(_list):
    del _list[0]

for i in range(len(a)):
    scheduler.enter(60*10*i, 1, delete, (a,))

t = threading.Thread(target=scheduler.run)

t.start()
1 голос
/ 13 октября 2010

вы можете создать фоновый процесс, который проверяет, сколько времени прошло, и удаляет нужный элемент ... или, если вы хотите создать подкласс списка, который удаляет его содержимое после определенного времени, вы можете сделать то же самое,просто позвонив в init

def __init__(self, time):
    #run subprocess to chek_espired elements

edit:

я написал пример, но это можно сделать гораздо лучше!

class MyList(list):
    def __init__(self,elems,  expires_time):
        list.__init__(self, elems)
        self.created = time.time()
        self.expires_time = expires_time
    def __getitem__(self, index):
        t = time.time()
        print t -  self.created
        if t - self.created > self.expires_time:
            self.created += self.expires_time
            self.pop(index)
            self.__getitem__(index)
        return list.__getitem__(self, index)

ps конечно вы можете легко вызвать личную ошибку, если программа попытается получить индекс из пустого списка

1 голос
/ 13 октября 2010

Похоже, что элементы в вашем массиве знают друг о друге, потому что в противном случае все они истекают в одно и то же время.

Я думаю, вы хотите создать подкласс списка, который удаляет его содержимое через определенное время.

0 голосов
/ 13 октября 2010

Вы можете использовать модуль time для очистки «массива» каждые 10 минут, проверяя временной интервал с момента запуска сценария.

Последний пример на http://effbot.org/librarybook/time.htm направит вас в правильном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...