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

AltStyle によって変換されたページ (->オリジナル) /