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

Arnaud Delobelle arnodel at googlemail.com
Fri Mar 19 14:15:20 CET 2010


On 19 March 2010 09:07, Scott Dial <scott+python-ideas at scottdial.com> wrote:
> On 3/19/2010 4:25 AM, Arnaud Delobelle wrote:
>> On 19 Mar 2010, at 03:43, Scott Dial <scott+python-ideas at scottdial.com>
>> wrote:
>>> 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.
>>>
>>
>> Why not just use default arguments?
>>
>
> My problem with this particular kludge is that rarely are these
> arguments meaningful as *arguments*. They become a part of the function
> definition that shows up in documentation. Worse to me is that the
> keyword names block those names from appearing in **kwds, which is
> problematic for creating a transparent function (e.g., when writing a
> decorator that takes an unknown set of keyword arguments) and evokes
> dynamic-scoping madness. Additionally, they are a source of subtle
> errors when extra arguments are passed to functions (although this is
> mitigated mostly by Py3's keyword-only arguments syntax).
>
> All of those problems go away with a magical @closure() decorator, but I
> realize that creating such a decorator would be quite a kludge
> in-and-of-itself. Perhaps it's a bit too clever.

I wrote such a decorator a while ago, I called it 'bind'.  It was
indeed quite a kludge, but if you're interested I can post it.  It
worked by rewriting the bytecode of the function it decorated.  If I
remember correctly, it has some limitations, e.g. it didn't work with
local functions i.e.

@bind(x=3)
def f():
    def g():
        return x
    return g

f()()

would return the current value of the global variable 'x' rather than
3.  I don't think I got round to solving this (it would require
looking at the constants in the code which are themselves code objects
an apply the same bytecode transformation recursively).

Also, it was for Python 2.X so I don't know if it would work as-is in Python 3.

-- 
Arnaud



More information about the Python-ideas mailing list