I am doing some PloneFormGen work. Currently PloneFormGen stores entered form entries internally as tuples without associated column information. If new columns (form fields) are added then the existing data becomes invalid.
This could be easily avoided storing data in ordered dictionaries, which retain both entered column order and column ids.
Does ZODB have data type equivalent of ordered dictionary? If possible even with matching API (Python dict-like item manipulation and access)?
You can use any ordered dict implementation out-of-the-box in the ZODB, but you'll have to mark the parent object (the object that refers to the ordered dict instance) as changed by using either parent = odict_instance every time you change it or by setting _p_changed to True. This will, of course, result in a new persistent record for the parent together with the ordered dict instance.
If you want the ordered dict instance itself to detect changes automatically, you'll probably have to build your own class as I am not aware of any current implementations. That said, it is probably exceedingly easy to do so, especially if you use the ZODB PersistentMapping class as a template on how to build a ordered version of the same. You can't use that class as a mixin, unfortunately, as it refers directly to UserDict methods instead of using super() calls (persistent.Persistent is not a new-style class).
Python 2.7 has a ordered dict class in the standard library. Presumably you are still using Python 2.6 in Plone, so you'd have to backport it. Once you've got it backported however, a PersistentOrderedDict implementation should be a straight copy from the PersistentMapping source code, with all instances of UserDict.IterableUserDict replaced with your OrderedDict port.
you'll probably have to build your own class as I am not aware of any current implementations.
You can find implementations of ZODB persisting ordered dicts based on PersistentDict and OOBtree here:
https://github.com/bluedynamics/node.ext.zodb/blob/master/src/node/ext/zodb/utils.py
This implementations are based on odict package:
http://pypi.python.org/pypi/odict
Since it's not possible to persist dict type inheriting objects to ZODB (because persistent.Persistent and dict has incompatible low level implementations) odict provides a way for easily hooking different base classes (using _dict_impl function internally all over the place). That is the reason why odict package is still used in favour of even python 2.7's ordered dict implementation or other 3rd party ordereddict implementations.
Both werkzeug and paste provide ordereddicts. You could no doubt pickle them for your purposes.
If a Python object can be pickled it can be persisted within the ZODB.
Take a look at PersistantMapping, from what I understand it should be sufficient to create a mix-in class like this:
class PersistantOrderedDict(PersistantMapping, OrderedDict):
Related
So I'm supposed to make a dictionary get ordered, and the way I'm doing it now is not valid;
dictionary = _collections.OrderedDict(sorted(dictionary.items()))
because it uses the library "_collections", is there any compact way to do this without an imported library?
No there isn't. If you want ordering you'll have to resort to using OrderedDict; that is the only means to retain order in a dict-like object for Python <= 3.5.
From Python 3.6, dictionaries remember the order of insertion by default (See: Dictionaries are ordered in Python 3.6+) so, you'll be able to feed a sorted sequence to it and get the ordering without use of any other modules (e.g OrderedDict). Despite this, it is best to wrap it in an OrderedDict; the ordering behavior of dicts in 3.6 is considered an implementation detail that you should not depend on.
Looks like there are multiple ways to do that but couldn't find the latest best method.
Subclass UserDict
Subclass DictMixin
Subclass dict
Subclass MutableMapping
What is the correct way to do? I want to abstract actual data which is in a database.
Since your dict-like class isn't in fact a dictionary, I'd go with MutableMapping. Subclassing dict implies dict-like characteristics, including performance characteristics, which won't be true if you're actually hitting a database.
If you are doing your own thing (e.g. inventing your own wheel) you might as well write the class from scratch (i.e. subclass from object), just providing the correct special members (e.g. __getitem__) and other such functions as described in the object data model, so that it quacks like a dict. Internally, you might even own a number of dicts (has-a) to help your implementation.
This way, you don't have to shoehorn your design to "fit" some existing implementation, and you aren't paying for some things you aren't necessarily using .This recommendation in part is because your DB-backed class will already be considerably more complex than a standard dict if you make it account for performance/caching/consistency/optimal querying etc.
I enjoy all the python libraries for scraping websites and I am experimenting with BeautifulSoup and IMDB just for fun.
As I come from Java, I have some Java-practices incorporated into my programming styles. I am trying to get the info of a certain movie, I can either create a Movie class or just use a dictionary with keys for the attributes.
My question is, should I just use dictionaries when a class will only contain data and perhaps almost no behaviour? In other languages creating a type will help you enforce certain restrictions and because of type checks the IDE will help you program, this is not always the case in python, so what should I do?
Should I resort to creating a class only when there's both, behaviour and data? Or create a movie class even though it'll probably be just a data container?
This all depends on your model, in this particular case either one is fine but I'm wondering about what's a good practice.
It's fine to use a class just to store attributes. You may also wish to use a namedtuple instead
The main differences between dict and class are the way you access the attributes [] vs . and inheritence.
instance.__dict__ is just a dict after all
You can even just use a single class for all of those types of objects if you wish
class Bunch:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
movie = Bunch(title='foo', director='bar', ...)
In your case you could use a class that inherits from dict (e.g class MyClass(dict)) so that you can define custom behavior to your dict-like class or use UserDict.
It depends on what you really mean for "perhaps almost no behaviour", if dict already provides what you need stay with it. Otherwise consider to subclass dict adding your specific behaviour. Since Python 2.2 it is possible. Using UserDict is an older approach to the problem.
You could also use a plain dictionary and implement the behaviour externally via some function. I use this approach for prototyping, and eventually refactor the code later to make it Object Oriented (generally more scalable).
You can see what a dictionary offers typing this at the interpreter:
>>> help({})
or referring to the docs.
I would stick to KISS (Keep it simple stupid). If you only want to store values you are better off with a dictionary, because you can dynamically add values at runtime. WRONG:(But you can not add new filds to a class at runtime.)
So classes are useful if they provide state and behaviour.
EDIT: You can add fields to classes in python.
I'm new to Python, and using Google App Engine, which is currently running only Python 2.5. Are there any built-in ways of doing an ordered dictionary, or do I have to implement something custom?
Django provides a SortedDict class, which has the same functionality. If you are using django, you can just use from django.utils.datastructures import SortedDict.
Even if you're not using django, you can still take advantage of that implementation. Just get the datastructures.py file from the django source and save it somewhere importable.
http://code.djangoproject.com/browser/django/trunk/django/utils/datastructures.py
you can sort a dict.items() list (of tuples) .. can't?
OrderedDict is new in 2.7, so no, there's no built-in way to do this - you'll have to implement your own.
Usually, an ordered dictionary is implemented as a dictionary of linked list nodes, linked in traversal order. This should be fairly straightforward to implement yourself.
The python shelf module only seems to be allow string keys. Is there a way to use arbitrary typed (e.g. numeric) keys? May be an sqlite-backed dictionary?
Thanks!
Why not convert your keys to strings? Numeric keys should be pretty easy to do this with.
You can serialize on the fly (via pickle or cPickle, like shelve.py does) every key, as well as every value. It's not really worth subclassing shelve.Shelf since you'd have to subclass almost every method -- for once, I'd instead recommend copying shelve.py into your own module and editing it to suit. That's basically like coding your new module from scratch but you get a working example to show you the structure and guidelines;-).
sqlite has no real advantage in a sufficiently general case (where the keys could be e.g. arbitrary tuples, of different arity and types for every entry) -- you're going to have to serialize the keys anyway to make them homogeneous. Still, nothing stops you from using sqlite, e.g. to keep several "generalized shelves" into a single file (different tables of the same sqlite DB) -- if you care about performance you should measure it each way, though.
I think you want to overload the [] operator. You can do it by defining the __getitem__ method.
I ended up subclassing the DbfilenameShelf from the shelve-module. I made a shelf which automatically converts non-string-keys into string-keys and returns them in original form when queried. It works well for Python's standard immutable objects: int, float, string, tuple, boolean.
It can be found in: https://github.com/North-Guard/simple_shelve