How can I pass in my locals and access variables directly from another function?

Let's say I have this:

def a(dict): locals().update(dict) print size def b(): size = 20 f(locals()) 

What do I need to do to access the size variable directly from a function? I know:

 size = dict["size"] 

but I think there should be a more direct way. I tried using locals().update(dict) , but that didn't work. Is there a better way?

+4
function variables python language-features
source share
6 answers

The Python compiler optimizes access to local variables by recognizing at compile time whether the calls that the function executes are local (i.e., names assigned or otherwise associated with the function). Therefore, if you code:

 def lv1(d): locals().update(d) print zap 

the compiler “knows” that barename zap NOT local (not assigned in the lv1 function), and therefore it compiles the code to access it as global, and not that d does not matter.

If you prefer slow and bloated code, you can defeat optimization by using exec inside the function - when the compiler sees the exec keyword, it KNOWS that you are trying to make your code as slow, bloated and buggy as possible, and therefore it works, doesn't optimizing in any way, roughly.

So, the following code works as you wish:

 def lv1(d): exec "" locals().update(d) print zap lv1({'zap': 23}) 

it emits 23 as you want.

I hope that from the above "calm humor" I realized that the technique is not recommended, but I would have better formulated it very explicitly: for dubious syntactic pleasure to write print zap instead of print locals()['zap'] , you They pay a healthy price with performance point of view. Nevertheless, like all kinds of dangerous tools that can be useful in rare cases for really experienced programmers at the guru level, who really really know what they are doing and why, exec is available for you, use it) at your whim: Python NOT standing in your way! -)

+15
source share

Does it help you somehow?

 def print_size(size=None): print(size) dict = {'size': 'XXL'} print_size(**dict) 
+1
source share

You can use locks to access the scope of another function:

 def b(): def a(): print size size = 20 a() 

The trick is to stack functions that belong to each other. Thus, the inner function a can access the local variables of the outer function b.

But I don’t know what you are actually doing, so I’m not sure if this helps.

+1
source share
 print size 

cannot work because the "size" is unknown when compiling the code. Your code will work if you change it as follows:

 def a(dict): locals().update(dict) print locals()["size"] def b(): size = 20 a(locals()) 

But since a comment on your question already suggests: This is very strange code. I am sure there are better solutions if you explain what you really want to do.

0
source share

I know, I know, the question is old, and the accepted answer is already great.

Just add two cents because it seems obvious but not mentioned: Make the size local by assigning it a value (default) explicitly.

 def a(dict): size = 20 # size default value <- quick (and dirty?) fix locals().update(dict) print (size) def b(): size = 20 a(locals()) 

Thus, the added line ( size = 20 ) in the file () makes the actual local variable without the need for exec , being compatible with python3 and without optimization optimization.

And how can this be useful?

Well, with this we can implement something like def f(x, *args, y=10) in python2, as this causes a syntax error in python2, but just works in python3:

 def f(x, *args, **kwargs): y = 10 locals().update(kwargs) print (x, y) 

The example above works in python2 and python3

0
source share
 def f(x,y,z,**kwargs): print x,y,z print kwargs d = {"x":1, "y":2, "z":3} f(**d) 1 2 3 {} def f(z,**kwargs): print z print kwargs f(**d) 3 {'y': 2, 'x': 1} 
0
source share

All Articles