first, an example:
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
im looking for suggestions on how to tackle the generic problem:
given a bunch of entities with a shared aspect. the aspect is used both for fast access to the entities and within each entity’s functionality. where should the aspect be placed:
- within each entity (not good for fast access)
- index only (not good for each entity’s functionality)
- both within each entity and as index (duplicate data/reference)
- somewhere else/somehow differently
the problem may be extended, say, if we want to use several indices to index the data (ssn, credit card number, etc.). eventually we may end up with a bunch of SQL tables.
im looking for something with the following properties (and more if you can think of them):
# 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
i want the object, indices, all to play nicely and seamlessly with each other.
please suggest appropriate design patterns
note:
the above example is just that, an example. an example used to portray the generic problem.
so please provide generic solutions (of course, you may choose to keep using the example when explaining your generic solution)
Consider this.
This
observerattribute implements an Observable that notifies its Observers of updates. This is the list of observers that must be notified of changes.Each attribute is wrapped with properties. Using Descriptors us probably better because it can save repeating the observer notification.
Use collections.ABC for more information on what must be implemented.
http://docs.python.org/library/collections.html#abcs-abstract-base-classes
If you want “generic” indexing, then your collection can be parameterized with the names of attributes, and you can use
getattrto get those named attributes from the underlying objects.Note. To properly emulate a database, use a set not a list. Database tables are (theoretically) sets. As a practical matter they are unordered, and an index will allow the database to reject duplicates. Some RDBMS’s don’t reject duplicate rows because — without an index — it’s too expensive to check.