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