[Python-ideas] setting function properties with a decorator syntax

Scott Dial scott+python-ideas at scottdial.com
Fri Mar 19 04:43:34 CET 2010


On 3/18/2010 10:33 PM, Fred Drake wrote:
> On Thu, Mar 18, 2010 at 10:28 PM, David Stanek <dstanek at dstanek.com> wrote:
>> I don't remember seeing much code using function properties. I would
>> probably just create a new decorator for this.
> 
> I've not either, but if we determine that this is a useful facility to
> include in the standard library, I'd be in favor of something like
> this:
> 
> @setattr(printable=True)
> def f():
>     """Example function"""
> 

For the sake of a head count, I have used function attributes for the
purpose of memoizing computations (both return values and intermediate
calculations). A representative example:

@setattr(primes=set(), composites=set())
def is_prime(n):
    if n <= 0:
        raise ValueError(n)
    elif n == 1:
        return True
    elif n in is_prime.primes:
        return True
    elif n in is_prime.composites:
        return False
    for p in is_prime.primes:
        if n % p == 0:
            is_prime.composites.add(n)
            return False
    is_prime.primes.add(n)
    return True

But honestly, the biggest problem I have with this pattern is that you
explicitly have to say the name of the function since there is no "self"
equivalent. I think it would be more maintenance-friendly to do:

def _(n):
    primes = set()
    composites = set()
    def is_prime(n):
        if n <= 0:
            raise ValueError(n)
        elif n == 1:
            return True
        elif n in primes:
            return True
        elif n in composites:
            return False
        for p in primes:
            if n % p == 0:
                composites.add(n)
                return False
        primes.add(n)
        return True
    return is_prime
is_prime = _()

Which is to say, I would be more amenable to adding such a feature if it
was building closure. And in that usage, it would seem to be more
generally useful and well-behaved.. outsiders don't normally modify
closures (if you want this sort of interface, you probably should define
a class).. it allows you to avoid naming the function in the function..
and it is a much closer substitute for the default arguments kludge that
is so commonly abused.

@closure(primes=set(), composites=set())
def is_prime(n):
    if n <= 0:
        raise ValueError(n)
    elif n == 1:
        return True
    elif n in primes:
        return True
    elif n in composites:
        return False
    for p in primes:
        if n % p == 0:
            composites.add(n)
            return False
    primes.add(n)
    return True

But, that's just my two cents.

-- 
Scott Dial
scott at scottdial.com
scodial at cs.indiana.edu



More information about the Python-ideas mailing list