Curious case of UnboundLocalError

Ben Bacarisse ben.usenet at bsb.me.uk
Fri Mar 30 07:13:36 EDT 2018


Johannes Bauer <dfnsonfsduifb at gmx.de> writes:
> I stumbled about something that I cannot quite explain while doing some
> stupid naming of variables in my code, in particular using "collections"
> as an identifier. However, what results is strange. I've created a
> minimal example. Consider this:
>> import collections
>> class Test(object):
> 	def __init__(self):
> 		z = {
> 			"y": collections.defaultdict(list),

This mention of collections refers to ...
> 		}
> 		for (_, collections) in z.items():

... this local variable.
> 			pass
>> Test()

The same thing would happen in a plain function:
 import collections
 
 def f():
 z = { "y": collections.defaultdict(list) }
 for (_, collections) in z.items():
 pass
 
 f()
> In my opinion, this should run. However, this is what happens on Python
> 3.6.3 (default, Oct 3 2017, 21:45:48) [GCC 7.2.0] on linux):
>> Traceback (most recent call last):
> File "x.py", line 11, in <module>
> Test()
> File "x.py", line 6, in __init__
> "y": collections.defaultdict(list),
> UnboundLocalError: local variable 'collections' referenced before assignment
>> Interestingly, when I remove the class:

The significant change is removing the function that creates a local scope.
> import collections

This introduces "collections" as a global ...
> z = {
> 	"y": collections.defaultdict(list),
> }
> for (_, collections) in z.items():

... and this uses that global ...
> 	pass
>> It works as expected (doesn't throw).

... except now collections is bound to a list (from the for) and no
longer refers to the module.
-- 
Ben.


More information about the Python-list mailing list

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