[Python-ideas] Quick idea: defining variables from functions that take the variable name

M.-A. Lemburg mal at egenix.com
Tue Jun 7 14:29:15 EDT 2016


On 07.06.2016 01:20, Guido van Rossum wrote:
> On Mon, Jun 6, 2016 at 4:14 PM, Barry Warsaw <barry at python.org> wrote:
> 
>> On Jun 07, 2016, at 12:53 AM, M.-A. Lemburg wrote:
>>
>>> This would work as well and indeed reads better, but you'd need
>>> to have the compiler generate:
>>>
>>>      x = obj
>>>      recordbinding(obj, 'x', 2)
>>>
>>> ie. pass in the object, the bound name and the line number
>>> and recordbinding would then have to decide what to do with the
>>> parameters.
>>
>> +1 although I'd bikeshed on the order of the arguments.

:-)

>>> I used the method variant, because a very common use case
>>> is to let the object know about the name under which it is
>>> now known to Python. This can be used to eg. define records,
>>> forms, mappings, etc.
>>
>> Yep.  So given the above, `recordbinding(obj, 'x', 2)` would of course be
>> free
>> to delegate to `obj.recordbinding('x', 2)`, but it would be up to the
>> decorator (and its author), not the compiler to do that delegation.

Right, your approach is more generic.

>>> I just wonder how we could tell the compiler to special
>>> case this decorator in a clean way.
>>
>> That's the rub, but I do think you're on to a good general solution to a
>> common set of problems.
>>
> 
> I think we're on to something here. Maybe. Perhaps.

One approach would be to define what a decorator means in front
of an expression (since that's currently a SyntaxError), without
adding any new syntactic sugar. Here's a sketch...

@decorator
x = obj

compiles to:

x = obj
decorator('x', obj, lineno)

(I'm using obj in the calls to decorator here - those would not
be new lookups, but instead work using DUP_TOP in the byte
code)

Things get a bit tricky when you use tuples on the left hand
side:

@decorator
a, b, c = obj

compiles to:

a, b, c = obj
decorator('a, b, c', obj, lineno)

Not sure whether this would be useful. Perhaps it's better not
to allow for such a use.

Same problem for star assignments:

@decorator
a, *b, c = obj

Multiple assignments would work, though:

@decorator
a = b = c = obj

compiles to:

a = b = c = obj
decorator('a', obj, lineno)
decorator('b', obj, lineno)
decorator('c', obj, lineno)

Augmented assigns are tricky, but would work as well:

@decorator
a += obj

compiles to:

a += obj
decorator('a', value, lineno)

(here value stands for the result of the += operation; in
byte code this would be a DUP_TOP before the STORE_FAST to 'a')

More complex right hand sides should not pose a problem,
since it's clear that only the result matters (which is pushed
to the stack and can be DUP_TOPed as necessary).

Looking at https://docs.python.org/3/reference/grammar.html, I think
those are all cases to consider, unless I missed one.

The grammar would need to be extended with:

"""
decorated: decorators (classdef | funcdef | async_funcdef | assign_expr)

assign_expr: NAME (augassign (yield_expr|testlist) |
                   ('=' (yield_expr|assign_expr))*)
"""

The above disallows testlist or star assignments.

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Experts (#1, Jun 07 2016)
>>> Python Projects, Coaching and Consulting ...  http://www.egenix.com/
>>> Python Database Interfaces ...           http://products.egenix.com/
>>> Plone/Zope Database Interfaces ...           http://zope.egenix.com/
________________________________________________________________________

::: We implement business ideas - efficiently in both time and costs :::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611
               http://www.egenix.com/company/contact/
                      http://www.malemburg.com/



More information about the Python-ideas mailing list