tags:

views:

57

answers:

2

I have written a class that will be used to store parameters in a convenient way for pickling. It overloads __setattr__ for convenient access. It also uses a list to remember the order in which attributes where added, so that the iteration order is predictable and constant. Here it is:

class Parameters(object):
    def __init__(self):
        self._paramOrder = []

    def __setattr__(self, name, value):
        self._paramOrder.append(name)
        object.__setattr__(self, name, value)

    def __delattr__(self, name):
        self._paramOrder.remove(name)
        object.__delattr__(self, name)

    def __iter__(self):
        for name in self._paramOrder:
            yield self.name

    def iteritems(self):
        for name in self._paramOrder:
            yield name, self.name

The problem is that __init__ calls my overloaded __setattr__ in order to add the _paramOrder to the instance dictionary. Is there a way to handle this without adding a special case to __setattr__?

+1  A: 

yes.

have it call super(Parameters, self).__setattr__() instead.

class Parameters(object):
    def __init__(self):
        super(Parameters, self).__setattr__('paramOrder', [])

    # etc.

Or am I missing something?

Another alternative is to just go straight to __dict__

class Parameters(object):
    def __init__(self):
        self.__dict__['paramOrder'] = []

    # etc.

This should work because you are not overriding __getattr__ so you can read it without anything getting in the way.

aaronasterling
I do that right now, but I still need a special case, because otherwise the name `_paramOrder` will be added to `_paramOrder`.
Space_C0wb0y
that's not the code you showed. This should bypass `Parameters`'s `__setattr__` method.
aaronasterling
@Aaron: You are right. I misunderstood, but now I see.
Space_C0wb0y
+2  A: 

Use this line in __init__ instead:

object.__setattr__(self, '_paramOrder', [])
Zooba