简单的python数据结构,它透明地保存在磁盘上

tastyp的Python项目详细描述


…Tastypy文档主文件,由
Sphinx Quickstart于2017年1月31日星期二15:18:42创建。
您可以完全根据自己的喜好调整此文件,但它至少应包含根"toctree"指令。


py:module::tastypy

最好在
`readthedocs<;http://python tastypy.readthedocs.io/en/latest/>;` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `
数据结构的迭代器按首次添加键的顺序生成键和值。

例如,您可以存储一个
长时间运行的程序的部分结果,并允许程序在
崩溃或中断后从中断的位置恢复。


included:

-pod(persistentoredreddict的别名):一个持久的类dict映射。
-tracker:一个子类专门用于跟踪长时间运行的程序中的重复任务的状态(例如,将其用作爬虫程序中URL的队列)。


合拍器注意:



安装代码块::bash


…_ persistentordereddict:
…_ pod:

``persistentordereddict`
===创建"pod"时提供路径
,数据将使用位于
位置的文件持久化:

。代码块::python

>;>;来自tastypy import pod
>;>;my_pod=pod('path/to/my.pod')
>;>;my_pod['foo']=bar'
>;>;exit()

。代码块::python

>;>;来自tastypy import pod
>;>;my_pod=pod('path/to/my.pod')
>;>;my_pod['foo']
'bar'

``pod``在大多数方面都是"dict"的意思。它们支持
相同的迭代机制,类似的"update()"实现,并且
它们的"len"对应于它们的条目数。

用于
序列化和反序列化。json的通用性足以表示很多数据,而且与pickle不同,它是安全的、独立的应用程序,并且可以跨程序和python版本进行互操作。持久性文件是可读的,很容易被人工或其他工具破解。

nd dict-like对象(任意
嵌套组合)。在序列化反序列化周期中,string like
将被强制为"unicode",list like to"list",dict like to
"dict"。在可能的情况下,保持数据与
程序的分离是一个很好的主意,因此坚持使用这些非常通用的数据类型s
可能是一个*启用*约束。

但是,"json"的一个怪癖可能非常出乎意料:

……警告:

``json.encode()``转换inte从'dict`\s到'unicode`\s的ger键
以符合json规范。这种怪癖是由
``tastypy``:

…代码块::python

>;>;my_pod[1]={1:1}
>;>;my_pod.sync();my_pod.revert();执行序列化/反序列化循环
>;>;my_pod[1]
{1':1}

`'.


不过,了解它是如何工作的,以及如何不破坏它是很好的。


通过键入"pod"所做的任何更改都将正确同步。但是,如果您对存储在"pod"中的可变类型进行引用,然后使用*that*引用对其进行变异,则无法让
该"pod"知道它,并且该更改不会被持久化。

例如:

代码块::python

>;>;my_pod['key']=[]
>;>;my_list=my_pod['key']
>;>;my_list.append(42)bad!不会同步的!
>;>>我的存储箱[键]。附加(42)好!这将是同步的!

``pod``跟踪内存中更改的值,并在有足够的值更改时(默认为1000)或当
程序终止时同步到
磁盘。(在创建"pod"时,可以使用
``sync` at``参数设置同步阈值。)


是否会丢失数据?
~~~~~~~~~~~~~~~~~~~~~~~~~~
"脏"值(内存和磁盘上不同的值)可以被视为与打开的文件对象的数据具有相同的状态,该文件对象的状态与用于写入的数据的状态相同。如果程序退出,由于未捕获的异常而崩溃,或者
接收到sigterm或sigint(例如,从ctrl-c),数据*将*同步。
但是,在python解释器segfaults或
程序接收到sigkill的异常情况下,不可能同步,因此不同步ized
数据将丢失。

我可以手动控制同步吗?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
通常您不需要,但您可以。若要立即对所有脏值执行一次性同步,请执行:py:meth:`pod.sync()
<;persistentordereddict.sync()>;`。要同步特定值,请使用
:py:meth:`pod.sync_key(key)<;persistentordereddict.sync_key()>;`。要为下一次同步标记密钥脏,请使用:py:meth:`pod.mark_dirty(key)
<;persistentordereddict.mark_dirty()>;`。要获取脏键集,请执行
:py:meth:`pod.dirty()<;persistentordereddict.dirty()>;`。您可以使用:py:meth:`pod.hold()
<;persistentordereddict.hold()>;`暂停自动同步,并使用:py:meth:`pod.unhold()
<;persistentordereddict.unhold()>;`重新激活。删除所有未同步的更改并还原到磁盘上存储的状态do:py:meth:`pod.revert()
<;persistentordereddict.revert()>;`。请参阅podref_ux。



对于文件,这是不安全的——当一个文件对象刷新时,它可能会覆盖另一个文件对象最近写入的数据。
但是"pod"打开到磁盘上的同一位置的行为类似于单例,因此它们实际上引用了相同的底层数据,使陈旧覆盖成为非pr奥布勒姆当然,如果您想让多个进程在同一个位置与"pod"交互,情况就完全不同了——为此,您应该使用一个带有独立内存的"sharedpodintro"。通过在创建时传递
``clone=false`,但不需要这样做。)

…_ podref:

``persistentordereddict``引用
----------

…py:class::pod

自动类::persistentordereddict
:成员顺序:按源
:成员:

…_共享数据中心:
…_共享PersistentOrderedDict:
…_ sharedpod:

使用``sharedpod```\s进行多进程处理
==========
若要使多个进程在同一位置使用``pod``\s,则需要使用``sharedpod```,它处理进程之间的同步。
打开单个``sharedpod``ins`然后将其分发给子对象
(例如,通过将其传递到"pipe"或"queue",或作为参数传递给"multiprocessing.process"或"multiprocessing.pool"。

警告:

不要创建指向磁盘上相同位置的多个"sharedpod"实例。创建一个"sharedpod"(磁盘上的每个位置),并与其他进程共享它。


sses的访问。
使用"sharedpod"所做的更改立即对所有进程可见。



。_ writetosharedpods:

writing to shared``sharedpod``\s
----------
``sharedpod``必须使用不同的策略来确保数据
正确同步。仅将值标记为脏值是不够的:需要将新值
转发到底层服务器。

任何时候你对一个"sharedpod"做了什么可以改变它的事情,你应该在"sharedpod.set"属性上执行它,而不是在"shardpod.set"本身上执行它。代码块::python

shared懔pod=tastypy.sharedpod('my.pod')


shared懔pod['foo']={bar':0,'baz':[]}错误!不会同步。
共享的"pod.set['foo']={'bar':4,'baz':[]}很好!

共享的"pod"['foo']['bar']+=1"坏"!不会同步。
共享存储区。设置["foo"]["bar"]+=1好!

共享的"pod"['foo']['baz'].append('fizz')不正确!不会同步。
共享_pod.set['foo']['baz'].append('fizz')很好!

``shared pod``` s ``.set``属性使用一些技巧来捕获
任意深度的"键控"和"索引"、方法调用、参数,并告诉
当它被`+=``等运算符操作时,切片分配如
``shared pod.set['a'[:]=[4]``等。然后,它会转发这个
信息,以便进行适当的处理和同步。

代码块::python

>;>print shared懔pod.set['foo']['baz'][0]
<;tastypy.[u deep懔proxy.deepproxy at 0x103ed8c90>;
>;
>;print shared懔pod['foo']['baz'][0]
fizz

与内部同步到磁盘相关的Raciness问题,它确保每个保持相同的进程总能看到最新的值,不管是同步到磁盘还是不同步。您可以使用sharedpod(或任何其他共享数据结构)。


通常,一个安全的
策略是让不同的进程读/写到非重叠的
``sharedpod```` s`密钥的子集。

为了证明这一点,我们将使用可以引入竞争条件的原型示例:递增一个值。
假设我们有一个worker函数,它将由一组不同的worker执行,看起来像这样:

代码块::python

def work(pod):
pod.set['some-key']+=1

,这看起来不错,但是`+=``运算符实际上对应于首先计算``old-val+1``的和,然后*将其分配回变量。
当进程a执行`+=``时,进程b c我们会一起更新
变量,在计算和之后,但在a将其赋值之前进行更新。所以,B的更新会丢失。要临时阻止其他进程修改"sharedpod",请使用:py:meth:`sharedpod.locked()
<;sharedpersistendordeddict.locked()>;`context manager,如下所示:

代码块::python

def work(shared_pod):
使用shared_pod.locked():
shared_pod.set['some-key']+=1

首先,任何一个"sharedpod"的方法,或者定义为"on"的方法,其值都可以被视为"原子的",因为在调用方法之前,内部会执行一个锁,然后再释放。e-list'].append('item')```,或
``del pod.set['some-dict']['some-key']```.
与上述相反,在值上使用
```+=``运算符时,您也不需要锁定上下文,这些值*是
实现*```` iadd``的可变对象,并执行操作*inplace*。例如,
对列表的扩展赋值不需要锁,例如
``pod.set['i-store-a-list']+=[1]`.


如果:

-从"sharedpod"读取值
-根据该值执行操作
-如果该值更改,则会很糟糕d在完成该操作之前
-其他进程可以修改该值


``sharedpod``多处理示例
在本例中,每个worker都读/写自己的
``sharedpod``子集,因此不需要锁定:

…代码块::python


_procs=5
init=[(i,none)for i in range(25)]
pod=tastypy.sharedpod('my.pod',init=init)
procs=[]
for i in range(num_procs):
proc=process(target=work,args=(pod,i,num_procs))
proc.start()
procs.append(proc)

for proc in procs:
proc.join()


for key,val in pod.iteritems():
print key,val


代码块:bash

$python共享pod示例。py
0
1 1
24
3 9
4 16
5 25
6 36
7 49
8 64
9 81
10 100
11 121
12 144
13 169
14 196
15 225
16 256
17 289
18 324
19 361
20 400
21 441
22 484
23 529
24 576

_ sharedpodreference:

sharedpersistentedordereddict reference
--------

…PY类::sharedpod

autoClass::sharedPersistentOrderedDict(路径,init={},gzip=false,文件大小=1000,同步时间=1000)


…py:attribute::设置


接受"sharedpod"上所有可变操作的属性。
例如:

代码块::python

shared_pod['some']['key']+=42坏!,将不会同步
共享舱。设置["some"]["key"]+=42好!

共享的"pod"['some']['list'].append('四十二')不正确!,将不会同步
共享的"pod.set['some']['list'].append('四十二')很好!

…automethod::close()
…automethod::locked()
…自动方法::lock()
…automethod::unlock()

*以下方法在功能上等同于*``pod``:

…py:method::update()
…py:method::mark_dirty()
…py:method::sync()
…py:method::sync_key()
…py:method::hold()

py:method::unhold()
…py:method::revert()
…py:method::iteritems()
…py:method::iterkeys()
…py:method::itervalues()
…py:method::items()
…py:method::keys()
…py:method::values()





…_进度跟踪程序:
…_ tracker:

``progresstracker`
=====

``tastypy.tracker```(简称"tastypy.progresstracker```)是pod的一个子类,它有助于跟踪长期运行的程序的进度,这些程序需要执行许多重复的任务,因此程序可以选择在
它停止的地方,以防发生碰撞。

tracker中的每个值表示一个任务,并存储该任务是否已完成、中止、尝试了多少次,以及您可能希望与之关联的其他数据。


成功完成,但最多只能尝试一些任务。

首先,我们将使用
regular pod来跟踪需要爬网的url。然后我们将
看看"tracker"如何支持这个用例。首先使用一个pod:

…代码块::python

def crawn(seed_url):

url_pod=tastypy.pod('urls.pod')
如果url pod[url]['done']:
继续

这个url
url_pod[url]['tries']+=1

他的url done
对于find_url中的find_url:
如果url不在url_pod中:
url_pod[url]={尝试:0,'done':false}
url_pod[url]['done']=true

如您所见,我们使用pod跟踪发现的url,
已经取了哪些,每次取多少次已经试过了。无论何时启动此程序,它都将只尝试对尚未成功爬网的URL进行爬网,而忽略已尝试至少3次的URL。


跟踪程序提供了一些支持此用例的工具。tracker中的所有条目
都是字典,它们至少有一个默认为"false"的"完成"标志,一个默认为"false"的"中止"标志,以及一个默认为"0"的"计数器"。`` tracker``\s有各种
方法来帮助跟踪任务,并允许您只遍历
没有完成、中止或尝试过多次的任务。使用"tracker",程序会像这样:

。代码块::python

def crawn(seed_url):

url撸tracker.add撸if撸absent(seed撸url)


eed
成功,找到的网址=爬网(url)
如果不成功:
继续

在上面的代码块中,``try_keys()``迭代器用于迭代
仅迭代未完成、未中止或已尝试的任务``max戡tries``次,
,同时对每个生成的任务递增```u tries``。
`` add_if廑absent(key)``方法用于初始化一个零次尝试的新任务,
,但前提是该任务不在跟踪程序中。"`mark\u done(key)"`
方法用于标记任务已完成。有关跟踪长期运行程序进度的其他方便方法,请参阅tracker参考资料。

使用"tracker"存储与任务相关的其他数据,如任务输出/结果。请记住,每个任务的条目都是一个"dict",其中最少包含"tries"、"done"、"aborted"和"aborted"键,所以不要用那些没有意义的值覆盖它们!

…_程序跟踪器:

``progresstracker``引用
--------

…autoclass::progresstracker

``progresstracker``支持
:py:class:`pod<;persistentordereddict>;`\s提供的所有方法,与update函数只有一个小的差异,并添加了许多管理
任务的方法。

automethod::update

``progresstracker``将以下方法添加到
:py:class:`pod<;persistentordereddict>;`:

*添加任务*

…自动方法::添加
…automethod::如果没有
则添加。automethod::添加多个
…automethod::如果不存在,则添加"许多"

*更改任务的状态*

…自动方法:标记"完成"
…自动方法:标记"未完成"
…automethod::增量尝试
…automethod::递减尝试
…automethod::重置尝试
…自动方法::中止
…automethod::unabort

*检查任务的状态*

…automethod::完成
…automethod::尝试
…automethod::已中止

…_门:

*决定是否应完成任务的门*

…automethod::应该做
…automethod::应该添加
…automethod::应该尝试
…automethod::应该尝试添加

…_迭代器:

*遍历要完成的任务*

…automethod::待办事项
…automethod::todo_键
…automethod::todo_值
…automethod::尝试项
…automethod::尝试键
…自动测量法::try_values

*检查所有任务的状态*

…自动方法::num_done
…automethod::分数已完成
…自动方法:完成百分比
…自动方法:未完成百分比

…automethod::num_已尝试
…automethod::分数已尝试
…automethod::尝试的百分比
…自动方法:未尝试的百分比

…automethod::num_已中止
…automethod::分数已中止
…automethod::已中止的百分比
…自动方法:未中止的百分比









…_ SharedProgressTracker:
…_ shareddprogresstracker:


sharedprogresstracker```sharedprogresstracker```\s多进程处理






sharedprogresstracker```sharedprogresstracker```````sharedpod````可以将sharedprogresstracker``` sharedtracker````` sharedprogresstracker`````` sharedprogresstracker```````````````````多进程处理。






====基本用法应用程序s.应创建一个"sharedtracker",并使用"queue"、"pipe"或参数
将其分发给子进程。所有"tracker"自己的用于更新任务状态的方法(例如"mark"done(key)或"increment"tries(key))
都保证与磁盘正确同步。
如果要添加或更改任务中存储的自己的数据,则对于
pod_uu\s,对"tracker.set"属性执行变异操作,而不是对"tracker"本身执行变异操作。有关说明,请参阅"writetosharedpods"。

``sharedprogresstracker``参考
--------


…py:class::sharedtracker

autoClass::sharedprogresstracker(path,max_tries=0,init={},gzip=false,file_size=1000,sync_at=1000)

| writeToSharedPods replace::正在写入"sharedPod"`\s
…| podref替换:``pod``引用
…| pod_ref替换:``pod``
…| S替换::\S
…| em Unicode::0x2014..em破折号
…| rsquo;Unicode::0x2019..右单引号
…| sharedpodintro替换:``sharedpod``
…| progtracker替换:``progresstracker`
…| sharedpodreference替换:``sharedpersistendordeddict`
…| persistentordereddict替换:``persistentordereddict``
…| sharedPersistentOrderedDict替换:``sharedPersistentOrderedDict``
…| pod替换:``pod``
…| sharedpod替换:``sharedpod``
…| progresstracker替换:``progresstracker`
…| tracker替换:`` tracker`
…| sharedprogresstracker替换:``sharedprogresstracker`
…| sharedtracker替换:`` sharedtracker``

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java在SWT中关闭CTabItem时如何获取警告消息?   java如何从中获取文本字符串   java带有(int[][])的方法意味着什么?   java我在创建这个安卓浮动泡泡动画时做错了什么?   将边距属性作为列表项的java表抛出异常ClassCastException   java如何在Storm拓扑中测量延迟和吞吐量   java如何在javafx中序列化事件?   java访问main()之外的线程   java如何强制某些方法仅对kotlin可见   java如何使用quartzscheduler启动具有多个crontrigger的作业?   java无法使用VM选项获取转储文件:引发OOM异常时出现HEAPDUMPONAUTOFMEMORYERROR   java无法在安卓中的FTP服务器上上载文件   java RecordView未显示   java有没有办法在Eclipse中隐藏/折叠虚张声势的注释?   java如何从xml中提取xml。广州?