Tôi đang theo sau một thùng chứa Python an toàn trong đó các giá trị được tự động xóa sau một thời gian. Liệu một lớp như vậy tồn tại?vùng chứa nơi giá trị hết hạn trong python
Trả lời
Đây là một phiên bản đề an toàn của 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)
mà có thể được sử dụng như thế này:
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)])
cảm ơn! Tôi thích thời gian chờ luồng. Ví dụ của tôi không phải là chủ đề an toàn phải không? Các tài liệu nói "deque là một thực hiện thay thế của hàng đợi không bị ràng buộc với các hoạt động chắp thêm nhanh() và popleft() nhanh chóng mà không yêu cầu khóa." – hoju
@Plumo: Tôi không có chuyên gia nào về đánh giá độ an toàn của luồng, nhưng tôi nghĩ phiên bản ExpireCounter của bạn có thể không phải là chủ đề an toàn. Trong phương thức 'add', lệnh gọi' datetime.now() 'có thể không được theo sau bởi lệnh gọi đến' self.events.append'. Hãy tưởng tượng nhiều chủ đề gọi phương thức 'add' gần như đồng thời. Rất nhiều cuộc gọi đến 'datetime.now', nhưng kết quả được nối vào' self.events' theo thứ tự lộn xộn. Nếu 'self.events' không được sắp xếp theo thứ tự thời gian, thì vòng lặp while trong phương thức' expire' có thể kết thúc quá sớm. Vì vậy, nó có thể không 'popleft' tất cả các yếu tố đã hết thời gian. – unutbu
Có lẽ bạn muốn có bộ nhớ cache LRU. Dưới đây là một tôi đã có nghĩa là để thử:
http://pypi.python.org/pypi/repoze.lru
Nó có vẻ là chủ đề an toàn.
không phải LRU. Tôi muốn một giá trị hết hạn sau chính xác thời gian chờ nhất định bất kể tôi có bao nhiêu giá trị và liệu tôi có truy cập chúng hay không. – hoju
Trong trường hợp đó, bạn có thể lưu trữ thời gian hết hạn với mỗi giá trị. Bạn muốn loại ngữ nghĩa vùng chứa nào: danh sách, bộ, dict hoặc cái gì khác? –
không quan tâm đến loại thùng chứa miễn là nó là chỉ an toàn – hoju
này là nhiều hơn hoặc ít hơn những gì tôi muốn bây giờ:
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)
có thể trùng lặp: http://stackoverflow.com/questions/3927166/automatically-expiring-variable – mouad
Tôi sau một chuỗi afe class với timeouts cho mỗi giá trị. Ví dụ đó sử dụng danh sách và thời gian chờ toàn cầu. – hoju