[pypy-dev] question about read only attributes of my file object

Laura Creighton lac at strakt.com
Sat Dec 4 15:48:14 CET 2004


I've a question about Python2.2 properties, setattr, getattr and friends.

I've implemented a file object, which depending on how you open it picks a
different implementation of a stream and uses that.

Currently I have code that looks like this:

    def __setattr__(self, attr, value):
        "Make some attributes readonly."
        if attr in ['mode', 'name', 'closed', 'encoding']:
            if hasattr(self, attr):
                raise AttributeError, "'%s' is a read-only Attribute" % attr
                # actually, write-once

        object.__setattr__(self, attr, value)

(in file, which inherits from object).  This works fine. When it comes to 
__getattr__ on the file object, what I want, if file does not provide its own
attribute is getattr(self.fd, attr) of whatever stream I have ended up making fd.

But Armin said that 2.2 provided properties (which I hadn't paid any attention
to) which would do this in a neater way.  Hmmm, I thought.  But I cannot
seem to get them to work.  According to Guido's doc which I read here,
http://www.python.org/2.2.3/descrintro.html#property

it looks to me as if they don't do what I want.  First I experimented with this:

Python 2.3.4 (#2, Sep 24 2004, 08:39:09)
[GCC 3.3.4 (Debian 1:3.3.4-12)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class C(object):
...     def __init__(self):
...             self.mode = 'rU'
...     def getval(self, val):
...             return self.__dict__[val]
...         mode = property(getval, None)
...
>>> a = C()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in __init__
AttributeError: can't set attribute

---
Ok, this property takes effect even in __init__, rats.

Try again:

>>> class C(object):
...     def __init__(self):
...             self.mode = 'rU'
...     def getval(self, val):
...             return self.__dict__[val]
...     def setval(self, attr, val):
...             if hasattr(self, attr):
...                 raise AttributeError, "'%s' is a read-only Attribute" % attr
...                 # actually, write-once
...         mode = property(getval, setval)
...
>>> a = C()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in __init__
TypeError: setval() takes exactly 3 arguments (2 given)

---

Well, this looks as if I would have to write a separate setval for each attribute
I want to pass once, and there is no way to give them all the same setval method.

Am I missing something obvious?  Probably.  But properties look singularily useless
to me right now.  I suppose you could get around this limitation using metaclasses,
but that looks like getting out a monkeywrench to crack a very small nut ...

Laura



More information about the Pypy-dev mailing list