Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Python 2, how do I write to variable in the parent scope?

I have the following code inside a function:

stored_blocks = {} def replace_blocks(m):     block = m.group(0)     block_hash = sha1(block)     stored_blocks[block_hash] = block     return '{{{%s}}}' % block_hash  num_converted = 0 def convert_variables(m):     name = m.group(1)     num_converted += 1     return '<%%= %s %%>' % name  fixed = MATCH_DECLARE_NEW.sub('', template) fixed = MATCH_PYTHON_BLOCK.sub(replace_blocks, fixed) fixed = MATCH_FORMAT.sub(convert_variables, fixed) 

Adding elements to stored_blocks works fine, but I cannot increase num_converted in the second subfunction:

UnboundLocalError: local variable 'num_converted' referenced before assignment

I could use global but global variables are ugly and I really don't need that variable to be global at all.

So I'm curious how I can write to a variable in the parent function's scope. nonlocal num_converted would probably do the job, but I need a solution that works with Python 2.x.

like image 298
ThiefMaster Avatar asked Jan 31 '11 13:01

ThiefMaster


People also ask

How do you use a variable in a scope Python?

You would use global within the scope of a function to indicate that you want to use a variable in the global scope and not in the local scope. In python 3, there is also the nonlocal keyword that allows you to indicate you want to modify a variable in an outer scope that isn't the global/module scope.

How do you access local variables outside the scope in Python?

1 Answer. Using the keyword "global", you can change the scope of a variable from local to global, and then you can access it outside the function.

How do you store something as a variable in Python?

In some programming languages you have to declare a variable before using them or define the information that will be stored in it, e.g., a number. However, in Python we just need to type the name of our variable, followed by an equals sign and a value to assign to it. This is called assigning a value to a variable.


1 Answers

Problem: This is because Python's scoping rules are demented. The presence of the += assignment operator marks the target, num_converted, as local to the enclosing function's scope, and there is no sound way in Python 2.x to access just one scoping level out from there. Only the global keyword can lift variable references out of the current scope, and it takes you straight to the top.

Fix: Turn num_converted into a single-element array.

num_converted = [0] def convert_variables(m):     name = m.group(1)     num_converted[0] += 1     return '<%%= %s %%>' % name 
like image 88
Marcelo Cantos Avatar answered Oct 24 '22 12:10

Marcelo Cantos