python - 如何快速从 Klepto 文件存档中删除多个项目?
问题描述
我正在使用 Klepto 存档来索引文件夹树中的文件规范。扫描树后,我想快速删除对已删除文件的引用。但简单地从文件存档中逐一删除项目是非常缓慢的。有没有办法将更改同步到存档,或一次删除多个密钥?(“同步”方法似乎只添加新项目)
@Mike Mckerns 对这个问题的有用回答仅涉及删除单个项目: Python Saving and Editing with Klepto
使用 files.sync() 或 files.dump() 似乎只是从缓存中追加数据,而不是同步删除。有没有办法从缓存中删除密钥,然后一次性同步这些更改。个别删除太慢了。
这是一个工作示例:
from klepto.archives import *
import os
class PathIndex:
def __init__(self,folder):
self.folder_path=folder
self.files=file_archive(self.folder_path+'/.filespecs',cache=False)
self.files.load() #load memory cache
def list_directory(self):
self.filelist=[]
for folder, subdirs, filelist in os.walk(self.folder_path): #go through every subfolder in a folder
for filename in filelist: #now through every file in the folder/subfolder
self.filelist.append(os.path.join(folder, filename))
def scan(self):
self.list_directory()
for path in self.filelist:
self.update_record(path)
self.files.dump() #save to file archive
def rescan(self):
self.list_directory() #rescan original disk
deletedfiles=[]
#code to ck for modified files etc
#check for deleted files
for path in self.files:
try:
self.filelist.remove(path) #self.filelist - disk files - leaving list of new files
except ValueError:
deletedfiles.append(path)
#code to add new files, the files left in self.filelist
for path in deletedfiles:
self.delete_record(path)
#looking to here sync modified index from modifed to disk
def update_record(self,path):
self.files[path]={'size':os.path.getsize(path),'modified':os.path.getmtime(path)}
#add other specs - hash of contents etc.
def delete_record(self,path):
del(self.files[path]) #delete from the memory cache
#this next line slows it all down
del(self.files.archive[path]) #delete from the disk cache
#usage
_index=PathIndex('/path/to/root')
_index.scan()
#delete, modify some files
_index.rescan()
解决方案
我明白了...您真的很关心从file_archive
.
好的我同意。当您想删除多个条目时,使用__delitem__
orpop
有点残酷。file_archive
减速是由于必须file_archive
为您删除的每个键加载和重写整个文件存档。dir_archive
对于一个或许多其他档案来说,情况并非如此……但对于一个file_archive
它是。所以应该补救...
更新:我添加了一种新方法,可以更快地删除指定的键......
>>> import klepto as kl
>>> ar = kl.archives.file_archive('foo.pkl')
>>> ar['a'] = 1
>>> ar['b'] = 2
>>> ar['c'] = 3
>>> ar['d'] = 4
>>> ar['e'] = 5
>>> ar.dump()
>>> ar.popkeys(list('abx'), None)
[1, 2, None]
>>> ar.sync(clear=True)
>>> ar
file_archive('foo.pkl', {'c': 3, 'e': 5, 'd': 4}, cached=True)
>>> ar.archive
file_archive('foo.pkl', {'c': 3, 'e': 5, 'd': 4}, cached=False)
以前(即在已发布的版本中),您可以廉价地pop
从本地缓存中获取所需的密钥,然后执行ar.sync(clear=True)
以删除存档中的关联密钥。但是,这样做假设您拥有所有要保存在内存中的密钥。因此,您现在可以(至少在即将发布的版本中)popkeys
在缓存和/或存档中删除任何不需要的密钥,而不是将所有密钥加载到内存中。
推荐阅读
- php - 如果只定义了这行代码代码,它是如何执行的?
- karate - 空手道:获取所有用户并使用参考 id 删除
- javascript - 将 nl2br 移植到 Javascript/React - 如何手动转义文本?
- c# - 动态计算队列中的等待时间
- python - 根据列约束生成列
- printing - iOS 13 AirPrint 问题:可以打印一次到 UIPrinter,随后出现控制台错误,例如 Print-Job failed: Printer not found
- c# - " "这里不允许,因为它没有扩展类 'System.Web.UI.Page'
- json - 在 IE 中将 JSON 显示为 HTML 而无需下载
- html - 我无法通过打开 HTML 文件看到我的 D3.js 设计
- sql - 多张同形桌子的ERD设计