python extension problem (newbie)

Michael P. Reilly arcege at shore.net
Wed Jun 2 10:47:41 EDT 1999


Douglas du Boulay <ddb at crystal.uwa.edu.au> wrote:
: Hi ,

: I've been trying to write a python extension in C to interface to a
: Fortran program
: and a class wrapper for the extension using the following code loosely
: adapted from Mark Lutz's Programming Python  stackmodule example.

: Unfortunately whereas his example works fine, mine goes into a recursive
: loop whenever an
: instance is instantiated.  It seems that the __getattr__  method of the
: wrapper class
: cannot find the getattr method of the extension library  and defaults to
: trying to call itself, infinitely
: recursively.

: Having spent about 8 hours trying to figure out why, I still have no
: idea.
: Help!
: Thanks

: Doug

:>>file oograsp.py

: import p2fgraspint

: class Grasp:
:     def __init__(self, start=None):
:         self._base = start or p2fgraspint.Grasp()
:         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):
:         return setattr(self._base, name, value)
                         ^^^^^^^^^^
This is the problem: inside your __setattr__ method, you are performing
a __getattr__ on an attribute that does not exist yet.  So your __init__
function is attempting to use a value that isn't set yet.  (cf. section
"3.3.2 Customizing attribute access" in the Python Reference Manual,
http://www.python.org/doc/current/ref/attribute-access.html.)

You either want to:

a) assign to "self.__dict__['_base']" in the __init__ method, or
  def __init__(self, start):
    self.__dict__['_base'] = start or p2fgraspint.Grasp()
    print "doing done"

b) check for the attribute being set in __setattr__ and perform the
operation based on that:
  def __setattr__(self, name, value):
    if name == '_base':
      self.__dict__[name] = value
    else:
      setattr(self._base, name, value)

I suggest (b)  it is better for when you change or add localized
attribute names later, and is better for subclasses (IMO).

(Also, setattr returns None, so you do not need the "return".)

  -Arcege





More information about the Python-list mailing list