Python becoming less Lisp-like

Kay Schluehr kay.schluehr at gmx.net
Wed Mar 16 13:55:33 EST 2005


Torsten Bronger wrote:
> Hallöchen!

Moin!

> [First, I wanted to say "descriptors" instead of "decorators" (I
> superseded my post).]
>
> The goal is to trigger function calls when attributes are accessed.
> This is called properties in C# (and maybe in Ruby, too).  Python
> now also has this concept.  What I find ugly is that it is not a
> syntax element.  It looks artificially added to the language.  In
> C#, the "set" and "get" methods form with its attribute a syntactic
> unity.  Everything is together, and no "property" function is
> necessary.

Some people refused properties in Python for exactly this reason.
Defining somewhat like:

def _get_X(self):
    return self._X

def _set_X(self,X):
    self._X = X

X = property(_get_X, _set_X )

in a Java-style fashion is indeed awfull and clumsy and that people
dismiss such boilerplate code is understandable.

But "Thinking in Java" in Python is probably no good idea allthough
this style can be found in Guidos property-examples presented in his
famous introduction on new-style classes as well:

http://www.python.org/2.2/descrintro.html

I thought for a long time that C# solved this problem with a superior
accurate and compact notion, but paying more attention to the
property() function itself and not to the declarative style getters and
setters opened me a more generic road to reason about desciptors:

def accessor(name, check=None, types=[]):
    '''
    Generic property creator.
    '''
    name  = "__"+name
    def get(obj):
        if not hasattr(obj,name):
            setattr(obj,name, None)
        return getattr(obj,name)

    def set(obj,value):
        if types:
            if not True in [isinstance(value,t) for t in types]:
                raise TypeError, "Can't assign %s to property
%s."%(value,name[2:])
        if check:
            if not check(value):
               raise TypeError, "Can't assign %s to property
%s."%(value,name[2:])
        else:
            setattr(obj,name,value)
    return property(get,set,None)



Now an example:


class X(object):
    a = accessor("a")
    b = accessor("b", types = (tuple,list))
    c = accessor("c", check = lambda x:hasattr(x,"__len__"))

a,b,c are indeed properties of X !

>>> x = X()
>>> x.b = [1,2,3] # o.k
>>> x.b
[1, 2, 3]
>>> x.b = 0  # raises a TypeError, because a tuple/list is expected
.
.


Regards Kay




More information about the Python-list mailing list