python文本框有上次记忆_Python中的持久记忆

我有一个昂贵的函数,它接受并返回少量数据(一些整数和浮点数)。我已经有了memoized这个函数,但我想让备忘录持久化。已经有几个线程与此相关,但我不确定某些建议方法的潜在问题,我有一些相当具体的要求:我肯定会同时从多个线程和进程中使用这个函数(都使用multiprocessing和来自不同的python脚本)

我不需要从这个python函数外部对memo进行读写访问

如果我不想在不小心损坏的情况下,我不想在写备忘录的时候把它弄坏,或者手动终止python进程(我不知道这有多现实)

我强烈希望不需要大型外部库的解决方案,因为我在一台运行代码的机器上的硬盘空间非常有限

我对跨平台代码的偏好很弱,但我可能只在Linux上使用它

This thread讨论了shelve模块,它显然不是进程安全的。其中两个答案建议使用fcntl.flock锁定搁置文件。然而,在this thread中的一些回答似乎表明这是一个充满问题的问题-但我并不确切地确定它们是什么。这听起来好像仅限于Unix(尽管显然Windows有一个等价的名称msvcrt.locking),而且锁只是“咨询性的”——也就是说,如果不检查文件是否被锁定,它不会阻止我意外地写入文件。还有其他潜在的问题吗?写入文件的副本并作为最后一步替换主副本,是否会降低损坏的风险?在

看起来dbm module不会比架子更好。我已经快速浏览了sqlite3,但它似乎有点过头了。This thread和{a7}提到了几个第三方库,包括ZODB,但是有很多选择,它们对于这个任务来说都显得过于庞大和复杂。在

有人有什么建议吗?在

更新:kindall在下面提到了IncPy,看起来确实很有趣。不幸的是,我不想回到Python2.6(我实际上在使用3.2),而且它看起来与C库一起使用有点尴尬(我大量使用了numpy和scipy等)。在

kindall的另一个想法很有启发性,但我认为将其应用于多个进程会有点困难——我想用文件锁定或数据库代替队列是最容易的。在

再看一下ZODB,它看起来确实非常适合这个任务,但是我确实想避免使用任何额外的库。我仍然不完全确定简单使用flock的所有问题是什么-我想一个大问题是进程在写入文件时或释放锁之前终止?在

所以,我接受了synthesizerpatel的建议,使用sqlite3。如果有人感兴趣,我决定做一个插入式替换dict,它将其条目作为pickle存储在数据库中(我不必费心在内存中保存任何内容,因为数据库访问和pickle相比,pickle已经足够快了)。我确信有更有效的方法来实现这一点(我不知道我是否仍然存在并发问题),但下面是代码:from collections import MutableMapping

import sqlite3

import pickle

class PersistentDict(MutableMapping):

def __init__(self, dbpath, iterable=None, **kwargs):

self.dbpath = dbpath

with self.get_connection() as connection:

cursor = connection.cursor()

cursor.execute(

'create table if not exists memo '

'(key blob primary key not null, value blob not null)'

)

if iterable is not None:

self.update(iterable)

self.update(kwargs)

def encode(self, obj):

return pickle.dumps(obj)

def decode(self, blob):

return pickle.loads(blob)

def get_connection(self):

return sqlite3.connect(self.dbpath)

def __getitem__(self, key):

key = self.encode(key)

with self.get_connection() as connection:

cursor = connection.cursor()

cursor.execute(

'select value from memo where key=?',

(key,)

)

value = cursor.fetchone()

if value is None:

raise KeyError(key)

return self.decode(value[0])

def __setitem__(self, key, value):

key = self.encode(key)

value = self.encode(value)

with self.get_connection() as connection:

cursor = connection.cursor()

cursor.execute(

'insert or replace into memo values (?, ?)',

(key, value)

)

def __delitem__(self, key):

key = self.encode(key)

with self.get_connection() as connection:

cursor = connection.cursor()

cursor.execute(

'select count(*) from memo where key=?',

(key,)

)

if cursor.fetchone()[0] == 0:

raise KeyError(key)

cursor.execute(

'delete from memo where key=?',

(key,)

)

def __iter__(self):

with self.get_connection() as connection:

cursor = connection.cursor()

cursor.execute(

'select key from memo'

)

records = cursor.fetchall()

for r in records:

yield self.decode(r[0])

def __len__(self):

with self.get_connection() as connection:

cursor = connection.cursor()

cursor.execute(

'select count(*) from memo'

)

return cursor.fetchone()[0]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值