Consider the following example:
i=7
j=8
k=10
def test():
i=1
j=2
k=3
return dict((name,eval(name)) for name in ['i','j','k'])
It returns:
>>> test()
{'i': 7, 'k': 10, 'j': 8}
Why eval does not take into consideration the variables defined inside the function? From the documentation, optionally you can pass a globals and a locals dictionary. What does it means?Finally, how can I modify this small case to make it work?
Python eval() Function The eval() function evaluates the specified expression, if the expression is a legal Python statement, it will be executed.
What is eval () in python and what is its syntax? Answer: eval is a built-in- function used in python, eval function parses the expression argument and evaluates it as a python expression. In simple words, the eval function evaluates the “String” like a python expression and returns the result as an integer.
The eval function parses the expression argument and evaluates it as a python expression. In other words, we can say that this function parses the expression passed to it and runs python expression(code) within the program.
eval evaluates any python code. int tries to convert any type to integer (float, bool, string ...). you got it.
Python eval () function parse the expression argument and evaluate it as a python expression and runs python expression (code) within the program. globals (optional): a dictionary to specify the available global methods and variables.
The local scope in a python program is defined for a block of code such as function. Each function in a python program has its own local scope in which all its variables and object names are defined. The local scope of a function is loaded when the function is called by any other function.
The main difference between eval () and exec () is that eval () can only execute or evaluate expressions, whereas exec () can execute any piece of Python code. The first argument to eval () is called expression. It’s a required argument that holds the string-based or compiled-code-based input to the function.
Global Scope. A variable created in the main body of the Python code is a global variable and belongs to the global scope. Global variables are available from within any scope, global and local. Example. A variable created outside of a function is global and can be used by anyone: x = 300. def myfunc ():
Generators are implemented as function scopes:
The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes generator expressions since they are implemented using a function scope.
So, the generator inside the dict()
constructor has its own locals()
dictionary. Now let's take a look at Py_eval
's source code, specially when both globals()
and locals()
are None:
if (globals == Py_None) {
globals = PyEval_GetGlobals();
if (locals == Py_None)
locals = PyEval_GetLocals();
}
So, for your example PyEval_GetLocals()
will be empty at the moment the loop is executing and globals()
will be the global dictionary. Note that i
, j
and k
defined inside the function are not in local scope of generator, rather they are in its enclosing scope:
>>> dict((name,eval(name, globals(), {})) for name in ['i', 'j', 'k'])
{'i': 7, 'k': 10, 'j': 8}
This occurs because the generator expression has a different scope to the function:
>>> def test():
i, j, k = range(1, 4)
return dict((j, locals()) for _ in range(i))
>>> test()
{2: {'.0': <listiterator object at 0x02F50A10>, 'j': 2, '_': 0}}
Using j
inside the scope binds it from the function, as that's the nearest enclosing scope, but i
and k
are not locally bound (as k
isn't referenced and i
is only used to create the range
).
Note that you can avoid this issue with:
return dict(i=i, j=j, k=k)
or a dictionary literal:
return {'i': i, 'j': j, 'k': k}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With