Private attributes

Magnus Lie Hetland mlh at vier.idi.ntnu.no
Tue Apr 9 06:28:27 EDT 2002


Just playing with the property descriptor API (and being absolutely
horrid with the inspect module <wink>)... In case anyone else might
find it intersting (or amusing):

-----------------------------------------------------
__metaclass__ = type
import inspect

def called_from(obj):
    try:
        frame = inspect.stack()[2][0]
        caller = frame.f_locals['self']
    except:
        return 0
    return caller is obj

class private:
    def __init__(self, name):
        self.name = name
    def __get__(self, obj, type=None):
        if called_from(obj):
            return obj.__dict__[self.name]
        else:
            raise AttributeError
    def __set__(self, obj, value):
        if called_from(obj):
            obj.__dict__[self.name] = value
        else:
            raise AttributeError
    def __delete__(self, obj):
        if called_from(obj):
            del obj.__dict__[self.name]
        else:
            raise AttributeError
-----------------------------------------------------

Example use:


class Test:
    x = private('x')
    def __init__(self):
        self.x = 42
    def test(self):
        print self.x

>>> t = Test()
>>> t.test()
42
>>> t.x = 43
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "private.py", line 27, in __set__
    raise AttributeError
AttributeError
>>> t.x

Having to supply the attribute name is a bit clunky, but could easily
be fixed by using a custom metaclass. Then one could just have a
marker constant or something for the metaclass to detect when creating
the class, e.g:

class Test2:
    x = private
    ...

- Magnus (who knows how naughty he has been, and who will never
  actually use this stuff ;)

--
Magnus Lie Hetland                                  The Anygui Project
http://hetland.org                                  http://anygui.org



More information about the Python-list mailing list