具有属性访问的dict实现:readonlydictproxy、frozendict、frozendorderedict、dict、orderedict

dictionaries的Python项目详细描述


buildcode qualitycode healthcoveragepypigithublicense: MIT

Quick overview

  • 属性样式项访问由此库的所有字典类提供。
  • 5个字典实现:
    • 具有属性样式项访问和更智能的带更新参数的copy()方法的标准字典:
      • Dict
      • OrderedDict
    • 前两个字典的不可变/哈希版本:
      • FrozenDict
      • FrozenOrderedDict
    • 可用于创建另一个字典实例的只读视图的包装器:
      • ReadonlyDictProxy

Usage

Quick-starter

安装库后,您可以按以下方式导入词典类:

fromdictionariesimportDict,OrderedDict,FrozenDict,FrozenOrderedDict,ReadonlyDictProxy

它们的接口是尽可能标准的,所以我假设您知道如何处理它们。

Attribute-style item access

在许多情况下,属性样式的字典项访问非常方便,但它有一些问题。最多的 显而易见的问题是字典的属性与项目键冲突。 因此,属性样式的访问有点“糟糕”(尤其是当您尝试实现它时),并且 为了解决这个问题,我最近提出了一种不同类型的属性样式访问实现。这个 library提供了通常的方法(这里和那里讨论过)和我的方法。(是的,我知道 更多的方法不是Python,但你必须试验找出什么有效什么无效…)以后我可能会 扔下其中一个。

“Classic” attribute-style dict item access (as people know it)

如前所述,dictionary实例的属性(如copy)与 你的物品。为了能够访问字典方法,我们必须为字典提供优先级 项目键上的属性。

>>>fromdictionariesimportDict>>>d=Dict(copy=True,name='example')>>>d.my_item=5# this is equivalent to d['my_item'] = 5>>>d{'my_item':5,'name':'example','copy':True}>>>d.my_item5>>>d.name'example'>>>d.copy# the 'copy' item conflicts with the copy method!!!<boundmethodExtendedCopyMixin.copyof{'my_item':5,'name':'example','copy':True}>

Attribute-style item access through the ^{tt1}$ attribute of the dictionary

我最近的发明帮助解决了字典属性和项键之间的冲突。通过键入 您还可以使用属性样式访问,而不必担心冲突:

>>>fromdictionariesimportDict>>>d=Dict(copy=True,name='example')>>>d.items.my_item=5>>>d{'my_item':5,'name':'example','copy':True}>>>d.items.my_item5>>>d.items.name'example'>>>d.items.copyTrue>>>d.items()# using items() the good old way still worksdict_items([('my_item',5),('name','example'),('copy',True)])

您可以使用字典中的items“方法”调用它,但也可以将其用作 对象,该对象提供对项目的属性样式访问。没有冲突,因为 是字典项的键。

除了属性样式项访问之外,items属性还提供了一组有限的典型字典接口:

  • __contains____iter____len__
  • 具有属性样式访问和下标符号的项分配/检索/删除。

如果必须传递要在其他地方访问的items对象,这将非常有用。

>>>fromdictionariesimportDict>>>d=Dict(copy=True,name='example',my_item=5)>>>'name'indTrue>>>iter(d.items)<dict_keyiteratorobjectat0x104254e08>>>>list(d.items)['my_item','name','copy']>>>len(d.items)3>>>deld.items['name']>>>deld.items.copy# no conflict with Dict.copy :-)>>>d{'my_item':5}

Dictionary classes

^{tt2}$ and ^{tt3}$

它们是“冻结的”/不变的,就像标准库提供的frozenset。创造之后 他们的价值在一生中不会改变。与其他不可变对象一样, 这些字典是可散列的,因为其中的所有对象也是可散列的。

>>>fromdictionariesimportFrozenDict>>>d=FrozenDict(item1=1,item2=2)>>>d['item3']=3# we shouldn't be able to modify an immutable objectTraceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:'FrozenDict'objectdoesnotsupportitemassignment>>>deld['item2']# we shouldn't be able to modify an immutable objectTraceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:'FrozenDict'objectdoesnotsupportitemdeletion>>>d<FrozenDict{'item1':1,'item2':2}>>>>hash(d)8310388587437647073

^{tt4}$

有时你不得不把一些字典传来传去,但你要确保没有人修改它们。在这个 case您应该做的是在字典周围创建一个ReadonlyDictProxy包装器,并传递 用包装纸代替原来的包装纸。ReadonlyDictProxy实例将把所有请求委托给 原始D除了那些涉及数据修改的请求(比如项分配/删除,update(), 等等……)。当然,如果修改包装好的字典,那么readonly代理的用户将注意到这些更改。 代理保留包装dict提供的大部分行为,例如,如果包装dict是有序的 那么readonly代理也按顺序运行。

>>>fromdictionariesimportReadonlyDictProxy,OrderedDict>>>wrapped=OrderedDict.fromkeys(['item1','item2','item3'])>>>proxy=ReadonlyDictProxy(wrapped)>>>wrappedOrderedDict([('item1',None),('item2',None),('item3',None)])>>>proxy<ReadonlyDictProxyOrderedDict([('item1',None),('item2',None),('item3',None)])>

对包装的dict实例的更改由只读代理反映:

>>>delwrapped['item3']>>>wrapped['new_item']='brand new'>>>wrappedOrderedDict([('item1',None),('item2',None),('new_item','brand new')])>>>proxy<ReadonlyDictProxyOrderedDict([('item1',None),('item2',None),('new_item','brand new')])>

尝试修改代理对象将失败:

>>>proxy['trying hard']='to assign'# the proxy is readonly, assignment failsTraceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:'ReadonlyDictProxy'objectdoesnotsupportitemassignment>>>delproxy['item1']# the proxy is readonly, deletion failsTraceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:'ReadonlyDictProxy'objectdoesnotsupportitemdeletion

使用copy方法复制ReadonlyDictProxy实例会创建另一个 ReadonlyDictProxy包装完全相同对象的实例:

>>># Both of these statements create another wrapper/proxy around wrapped:>>>proxy_copy=proxy.copy()>>>proxy_copy2=ReadonlyDictProxy(wrapped)>>>>>># Now we have 3 proxy objects wrapping the same dictionary (wrapped):>>>wrapped.clear()>>>wrapped.items.woof='woof'>>>proxy<ReadonlyDictProxyOrderedDict([('woof','woof')])>>>>proxy_copy<ReadonlyDictProxyOrderedDict([('woof','woof')])>>>>proxy_copy2<ReadonlyDictProxyOrderedDict([('woof','woof')])>

Extended ^{tt5}$ method

除了ReadonlyDictProxy之外,所有字典类都有一个copy方法来接收**kwargs。这些 关键字参数被视为字典项,并用于创建用它们更新的副本。

>>>fromdictionariesimportDict>>>d=Dict(a=0,b=1)>>>d2=d.copy(b=2,c=3)>>>d{'a':0,'b':1}>>>d2{'a':0,'b':2,'c':3}

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

推荐PyPI第三方库


热门话题
java如何使用JNA创建同一库的多个实例?   java在将Graphql查询作为JSON字符串传递时收到意外的令牌错误   OAuth2 oltu的java问题   java桌面应用程序使用的好的嵌入式数据库是什么?   java Firebase数据库高级查询选项   java正在使磁盘上的EhCache元素过期   java 安卓还原处于backstack中的片段的实例状态   XMemcached中的java异步集   java TimescaleDB是否使用与Postgresql完全相同的JDBC驱动程序?   java从网站c读取信息#   检查java Android中的字符串是否只包含数字和空格   c#如何向web服务发送特殊字符?   grails无法调用需要java的方法。lang.类参数?   java我在组合框中调用的方法不会运行所有代码,它只运行部分代码   java发送带有标头的HTTP GET请求