python:字典困境:如何根据属性正确地索引对象
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python:字典困境:如何根据属性正确地索引对象,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3808字,纯文字阅读大概需要6分钟。
内容图文
首先,一个例子:
given a bunch of Person objects with
various attributes (name, ssn, phone,
email address, credit card #, etc.)now imagine the following simple
website:
- uses a person’s email address as unique login name
- lets users edit their attributes (including their email address)
if this website had tons of users,
then it make sense to store Person
objects in a dictionary indexed by
email address, for quick Person
retrieval upon login.however when a Person’s email address
is edited, then the dictionary key for
that Person needs to be changed as
well. this is slightly yucky
即时寻找有关如何解决一般问题的建议:
给出了一堆具有共享方面的实体.该方面既用于快速访问实体,也用于每个实体的功能.应该在哪里放置方面:
>在每个实体内(不适合快速访问)
>仅索引(不适合每个实体的功能)
>在每个实体内和作为索引(重复数据/参考)
>其他地方/某种程度上不同
如果我们想要使用多个索引来索引数据(ssn,信用卡号等),问题可能会延长.最终我们可能会得到一堆SQL表.
我正在寻找具有以下属性的东西(如果你能想到它们还有更多):
# create an index on the attribute of a class
magical_index = magical_index_factory(class, class.attribute)
# create an object
obj = class()
# set the object's attribute
obj.attribute= value
# retrieve object from using attribute as index
magical_index[value]
# change object attribute to new value
obj.attribute= new_value
# automagically object can be retrieved using new value of attribute
magical_index[new_value]
# become less materialistic: get rid of the objects in your life
del obj
# object is really gone
magical_index[new_value]
KeyError: new_value
我希望对象,索引,所有这些都能很好地相互无缝地发挥作用.
请建议适当的设计模式
注意:
上面的例子只是一个例子.用于描述一般问题的示例.
所以请提供通用解决方案(当然,您可以选择在解释通用解决方案时继续使用该示例)
解决方法:
考虑一下.
class Person( object ):
def __init__( self, name, addr, email, etc. ):
self.observer= []
... etc. ...
@property
def name( self ): return self._name
@name.setter
def name( self, value ):
self._name= value
for observer in self.observedBy: observer.update( self )
... etc. ...
此observer属性实现一个Observable,通知其Observers更新.这是必须通知变更的观察员列表.
每个属性都包含属性.使用描述符我们可能更好,因为它可以节省重复观察者通知.
class PersonCollection( set ):
def __init__( self, *args, **kw ):
self.byName= collections.defaultdict(list)
self.byEmail= collections.defaultdict(list)
super( PersonCollection, self ).__init__( *args, **kw )
def add( self, person ):
super( PersonCollection, self ).append( person )
person.observer.append( self )
self.byName[person.name].append( person )
self.byEmail[person.email].append( person )
def update( self, person ):
"""This person changed. Find them in old indexes and fix them."""
changed = [(k,v) for k,v in self.byName.items() if id(person) == id(v) ]
for k, v in changed:
self.byName.pop( k )
self.byName[person.name].append( person )
changed = [(k,v) for k,v in self.byEmail.items() if id(person) == id(v) ]
for k, v in changed:
self.byEmail.pop( k )
self.byEmail[person.email].append( person)
... etc. ... for all methods of a collections.Set.
使用collections.ABC获取有关必须实现的内容的更多信息.
http://docs.python.org/library/collections.html#abcs-abstract-base-classes
如果您想要“通用”索引,那么您的集合可以使用属性的名称进行参数化,并且您可以使用getattr从底层对象获取这些命名属性.
class GenericIndexedCollection( set ):
attributes_to_index = [ ] # List of attribute names
def __init__( self, *args, **kw ):
self.indexes = dict( (n, {}) for n in self.attributes_to_index ]
super( PersonCollection, self ).__init__( *args, **kw )
def add( self, person ):
super( PersonCollection, self ).append( person )
for i in self.indexes:
self.indexes[i].append( getattr( person, i )
注意.要正确模拟数据库,请使用集合而不是列表.数据库表是(理论上)集.实际上,它们是无序的,索引将允许数据库拒绝重复.有些RDBMS不会拒绝重复的行,因为 – 没有索引 – 检查它太昂贵了.
内容总结
以上是互联网集市为您收集整理的python:字典困境:如何根据属性正确地索引对象全部内容,希望文章能够帮你解决python:字典困境:如何根据属性正确地索引对象所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。