PyObject *data - access to raw data?

Donn Cave donn at u.washington.edu
Tue Aug 8 12:39:28 EDT 2000


Quoth Thomas Gagne <tgagne at ix.netcom.com>:
...
| It would seem the pack and unpack methods are great for creating a structure a
| once, but not so great at accessing members of a structure for purposes of
| manipulation.  I've decided to create a class that uses a dictionary to mainta
| values for the members.  It uses a method called asBytes() to return the strin
| by struct.pack().  I should probably call it asString() since I'll document th
| arguments to send and recv and string arguments.

That looks good.  You could also call it __str__, though there is some
difference of opinion on this.  __str__ supports the str() function.
For some people, this should be a ``friendly'' text representation,
i.e. I guess readable.  For me, it's the object qua string, and if that's
readable, fine.  (This is particularly in contrast to __repr__, which
I think everyone agrees should be text.)  Anyway, I guess the most
likely advantage of calling it __str__ is that it would be invoked
automatically in %s formatting.

| Of course, right not its all buried inside my IsdHeader class, but I'm thinkin
| create a more general class called CStructure that defines all the methods for
| things, then subclassing it to create IsdHeader.

Well, it sounds like you're having fun.  From a practical point of view
it sounds like we're approaching overkill, but that's a judgement call.

Speaking of overkill, I think you are probably finding that your read/write
accessor overloading isn't working.  Unlike C++, Python doesn't support
different functions with the same name but different signature.  You can
simulate it with a kind of varargs feature (try a parameter declared with
a leading "*"), or with default arguments, but it's not commonly done and
for me it isn't idiomatic Python.  Might as well say getstatus()/setstatus().

Now, for a really intrusive accessor feature that is occasionally used
in Python code (I think usually to the sorrow of everyone concerned, but
others might disagree), consider this:

    class T:
        def __init__(self):
            self.__dict__ = {'x': 0, 'y': 0}
        def __getattr__(self, name):
            print 'getattr', repr(name)
            if name == 'xy':
                return self.x * self.y
            else:
                raise AttributeError, name
        def __setattr__(self, name, value):
            print 'setattr', repr(name), repr(value)
            if self.__dict__.has_key(name):
                self.__dict__[name] = value
            else:
                raise AttributeError, name

    t = T()
    print t.x
    print t.xy
    t.x = 5
    t.y = 2
    print t.x
    print t.xy
    print dir(t)

I think the most useful thing about this is that since you know it's
there in case you need it, you can relax and just code direct access
to class instance attributes and avoid the probably pointless hassle
of a pair of accessor functions dedicated to each attribute.  Then if
changes to the class mean you need to calculate a value on access, you
can use these functions to do it -- in this extremely unlikely case,
and 99 out of 100 classes you write will never need any such thing.
Note that __getattr__ is called for only those attributes that don't
already appear in the instance's __dict__.

	Donn Cave, donn at u.washington.edu



More information about the Python-list mailing list