Problem/bug with class definition inside function definition

Ned Batchelder ned at nedbatchelder.com
Tue May 8 07:04:10 EDT 2018


On 5/8/18 3:55 AM, Alexey Muranov wrote:
> Sorry, i was confused.  I would say that this mostly works as 
> expected, though the difference between
>
>    x = 42
>
>    class C:
>        x = x  # Works
>
> and
>
>    def f2(a):
>        class D:
>            a = a  # Does not work <<<<<
>        return D
>
> is still surprising to me.
>
> Otherwise, probably the solution with
>
>    def f(a):
>        _a = a
>        class D:
>            a = _a
>        return D
>
> is good enough, if Python does not allow to refer "simultaneously" to 
> variables from different scopes if they have the same name.
>
> Alexey.

I'm curious to see the real code you're writing that uses this style of 
class creation.  It feels like there might be an easier way to achieve 
your goal.

--Ned.
>
>
> On Tue, 8 May, 2018 at 12:21 AM, Alexey Muranov 
> <alexey.muranov at gmail.com> wrote:
>> To be more exact, i do see a few workarounds, for example:
>>
>>
>>    def f4(a):
>>        b = a
>>        class D:
>>            a = b  # Works
>>        return D
>>
>> But this is not what i was hoping for.
>>
>> Alexey.
>>
>> On Tue, 8 May, 2018 at 12:02 AM, Alexey Muranov 
>> <alexey.muranov at gmail.com> wrote:
>>> I have discovered the following bug or problem: it looks like i am 
>>> forced to choose different names for class attributes and function 
>>> arguments, and i see no workaround.  Am i missing some special 
>>> syntax feature ?
>>>
>>> Alexey.
>>>
>>> ---
>>> x = 42
>>>
>>> class C1:
>>>    y = x  # Works
>>>
>>> class C2:
>>>    x = x  # Works
>>>
>>> # ---
>>> def f1(a):
>>>    class D:
>>>        b = a  # Works
>>>    return D
>>>
>>> def f2(a):
>>>    class D:
>>>        a = a  # Does not work <<<<<
>>>    return D
>>>
>>> def f3(a):
>>>    class D:
>>>        nonlocal a
>>>        a = a  # Does not work either <<<<<
>>>    return D
>>>
>>> # ---
>>> def g1(a):
>>>    def h():
>>>        b = a  # Works
>>>        return b
>>>    return h
>>>
>>> def g2(a):
>>>    def h():
>>>        a = a  # Does not work (as expected)
>>>        return a
>>>    return h
>>>
>>> def g3(a):
>>>    def h():
>>>        nonlocal a
>>>        a = a  # Works
>>>        return a
>>>    return h
>>>
>>> # ---
>>> if __name__ == "__main__":
>>>    assert C1.y == 42
>>>    assert C2.x == 42
>>>
>>>    assert f1(13).b == 13
>>>
>>>    try:
>>>        f2(13)  # NameError
>>>    except NameError:
>>>        pass
>>>    except Exception as e:
>>>        raise Exception( 'Unexpected exception raised: '
>>>                         '{}'.format(type(e).__name__) )
>>>    else:
>>>        raise Exception('No exception')
>>>
>>>    try:
>>>        f3(13).a  # AttributeError
>>>    except AttributeError:
>>>        pass
>>>    except Exception as e:
>>>        raise Exception( 'Unexpected exception raised: '
>>>                         '{}'.format(type(e).__name__) )
>>>    else:
>>>        raise Exception('No exception')
>>>
>>>    assert g1(13)() == 13
>>>
>>>    try:
>>>        g2(13)()  # UnboundLocalError
>>>    except UnboundLocalError:
>>>        pass
>>>    except Exception as e:
>>>        raise Exception( 'Unexpected exception raised: '
>>>                         '{}'.format(type(e).__name__) )
>>>    else:
>>>        raise Exception('No exception')
>>>
>>>    assert g3(13)() == 13
>>>
>>
>




More information about the Python-list mailing list