python extension problem (newbie)

Tim Peters tim_one at email.msn.com
Tue Jun 1 23:01:05 EDT 1999


[Douglas du Boulay]
> I've been trying to write a python extension in C to interface to
> a Fortran program and a class wrapper for the extension ...
> It seems that the __getattr__  method of the wrapper class cannot
> find the getattr method of the extension library ...

The good news is that it has nothing to do with your extension library, as
you can see by running this all-Python one-file equivalent:

class X:
    pass

class Grasp:
    def __init__(self, start=None):
        self._base = start or X()
        print "doing done"                  # which is never executed
    def __getattr__(self, name):
        print "called getattr"              # executed  endlessly
        return getattr( self._base , name)
    def __setattr__(self, name, value):
        print "called setattr"
        return setattr(self._base, name, value)

i = Grasp()

__init__ gets back from X() fine, and tries to bind self._base to the
result.

But you defined __setattr__, so trying to bind self._base calls __setattr__
(note that I put a "called setattr" print in there -- which, had you done
that, would have provided the clue you're missing!  __setattr__ is your real
problem, not __getattr__).

The first thing __setattr__ does is try to look up self._base.  But _base
hasn't been bound yet, so __getattr__ is called.

The first thing __getattr__ does is also to try to look up self._base.  But
_base still hasn't been bound yet, so __getattr__ is called.

The first thing __getattr__ does is also to try to look up self._base.  But
_base still hasn't been bound yet, so __getattr__ is called.

The first thing __getattr__ does is also to try to look up self._base.  But
_base still hasn't been bound yet, so __getattr__ is called.

The first thing __getattr__ does is also to try to look up self._base.  But
_base still hasn't been bound yet, so __getattr__ is called.

The attentive reader will detect a subtle pattern <wink>.

Defining __setattr__ is powerful but delicate, and you fell into a common
trap (well, common among people who muck with this stuff at all ...).  The
easiest way out is to bypass the killer __setattr__ by changing the first
__init__ line to

        self.__dict__['_base'] = start or X()

the-attribute-that-cannot-be-set-is-not-the-true-attribute-ly y'rs  - tim






More information about the Python-list mailing list