Properties, Methods, Events

Alex Martelli aleaxit at yahoo.com
Tue May 8 13:38:33 CEST 2001


"John Flynn" <transpicio at yahoo.com.au> wrote in message
news:XwJJ6.2678$ZJ.100694 at ozemail.com.au...
> I quite like the simple Properties-Methods-Events paradigm used by Delphi
> (and recently C#).

And Borland C++ and Microsoft Visual C++ as a non-standard extension, FWIW.
It's quite popular on PCs:-).

> My question is: has anyone emulated this in Python, eg. by overriding
> __setattr__ ?

Sure, it IS pretty trivial after all.  Here's a typical example:

class Props:
    def __setattr__(self, name, value):
        setter = getattr(self, 'set_'+name, None)
        if setter is None: self.__dict__[name]=value
        else: setter(value)
    def __getattr__(self, name):
        if name.startswith('get_'): raise AttributeError
        getter = getattr(self, 'get_'+name, None)
        if getter is None: raise AttributeError
        else: return getter()

class WithProps(Props):
    def __init__(self, initSpam=None):
        self.__spam = initSpam
    def get_spam(self):
        return self.__spam
    def set_spam(self, value):
        self.__spam = value

wp = WithProps(23)
print wp.spam
wp.spam += 100
print wp.spam

Any class desiring client code to use it with "property"
syntax just needs to inherit from mixin class Props (and
ensure its __setattr__ and __getattr__ special methods
are called -- it's automatic if it doesn't override them,
if it does it must be sure to delegate to them at need,
as usual) and implement methods named get_XXX and set_XXX
and with the obvious signature for any XXX property it
wants to expose.  That's it -- the getters and setters
will now automatically be called when appropriate, upon
client-code use of attribute-syntax.


> I'm going to try this out for fun, but I'd be interested to hear of
anyone's
> views on how it is best done in Python (or why it shouldn't be done at
all)

I think it's best done in a mixin (why rewrite, or copy
and paste, when you can reuse!).  And I think it's most
often better than have client code calling get_foo and
set_bar all over the place!  You can freely expose your
attributes to client code, AND switch to getter and setter
methods, *transparently to client code*, if and when you
find out a given attribute needs to be 'wrapped' upon
access and/or setting.  "Do the simplest thing that could
possibly work", &c.  I believe this possibility is in fact
what makes Python-inappropriate the common Java/C++ idiom
of exposing any attribute you DO need to expose through
getter and setter methods *ALWAYS*, "just in case".

Hmmm, wonder if this deserves a Cookbook recipe...


Alex






More information about the Python-list mailing list