Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle call to __setattr__ from __init__?

Tags:

python

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__?

like image 574
Björn Pollex Avatar asked Oct 06 '10 09:10

Björn Pollex


2 Answers

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.

like image 157
aaronasterling Avatar answered Sep 20 '22 12:09

aaronasterling


Use this line in __init__ instead:

object.__setattr__(self, '_paramOrder', [])
like image 33
Zooba Avatar answered Sep 22 '22 12:09

Zooba