Attribute Assignment Order in a Class Definition

I want to define a class this way:

class List(Base): hp = Column(int,...) name = Column(str,...) 

This class represents a list, I can define / modify / encode the Base and Column class. Is there a way to find out the order in which I defined the hp / names attributes? For example, I want to define a method that can do this:

 l = List() l.show() [(hp,16),(name,roger)] # in this order 
+4
source share
3 answers

Internally, attribute definitions are stored in a dictionary that does not preserve the order of elements. You could probably change the handling of the attributes in the base class or keep the creation order, for example:

 class Column: creation_counter = 0 def __init__(self): self.creation_counter = Column.creation_counter Column.creation_counter += 1 class Base: def show(self): fields = [(name, (obj, obj.value)) for name, obj in self.__class__.__dict__.items() if isinstance(obj, Column)] fields.sort(lambda (name1, (obj1, value1)), (name2, (obj2, value2)): cmp(obj1.creation_counter, obj2.creation_counter)) return fields 

Django preserves the order of form fields in a similar way, although more complex. If you're interested, look at the source of Django forms and fields

+7
source

I think you need something like this:

 import inspect class List(Base): hp = Column(int,...) name = Column(str,...) def show(self): public_bits = [(x, getattr(self, x)) for x in dir(self) if not x.startswith('__')] return [(x, y) for (x, y) in public_bits if not inspect.ismethod(y)] 

Unfortunately, dir returns attributes in alphabetical order, so this may not exactly solve your problem.

0
source

Class and instance attributes are inherently unordered because they are stored in a dictionary.

There are several options:

1) classes defined with __slots__ do not use a dictionary, and the space for attributes is pre-allocated. I assume that the attributes are therefore ordered, so it’s basically possible to get the data. However, there are problems using the slots, and this is not recommended.

2) add the list / tuple attribute to the class with attribute order.

3) use the collection.namedtuple object to store attributes. A named element is a tuple in which you can give names to elements, and is similar to structure C. This will only work with Python 2.6. Since tuples are immutable, you will not be able to change attributes after creation - this may or may not be a problem depending on the class.

Edit:

Reflection __slots__ will not work, since I think that they apply only to instances, and not to class attributes.

0
source

All Articles