I'm trying to write a code with exec and eval function to read lists of variables from a numpy .npz file.
When I ran the code without defining it as a function def, the code worked. However, when I ran the code as a function, i.e. read_file_npz("file_address") , the python 3.7 kept pop up message saying that templet_1h was not defined.
def read_file_npz(file_names_2):
import numpy as np
Delete_elements=["arr_0"]
evaluate_1= "templet_1h=np.load(\"./" +file_names_2+ ".npz\")";
exec(evaluate_1)
for i in (templet_1h.files):
if not ( (i in Delete_elements) ):
evaluate_2="global "+i;
exec(evaluate_2)
evaluate_2= i+"="+"templet_1h[\"" + i + "\"]";
exec(evaluate_2)
What's wrong with the warning and how to modify it?
I tried to declear templet_1h before the code as list(), but then the warning became .files had no ... towards lists, as if evaluate_1 was never ran.
Use exec(evaluate_1, globals()) instead to use the global dictionary for global and local variables in exec.
The code adds the defined variable to the global dictionary. Adding it as local variable of a function is not possible.
Related
Hey where doe Python store variables in a function and how do i access them
Lets say i have the following code:
import ctypes
def reveal():
me = "where"
print(id(me))
reveal() # memory_address
reveal() # same memory_address
ctypes.c_long.from_address(memory_address).value #1
from this i conclude that the variable has to be stored somewhere
i cant find it in globals() and it is not in the function __dict__
i dont know where to look for it or is it not accessible from outside of the function scope
No way. This variable is declared in the function's local scope and cannot be accessed outside of this function.
My friend asked me to build a function that can execute code in a for loop so, I was doing that and I was using exec in the same file I was declaring a variable name, now when I access name from exec, it says NameError: name 'name' is not defined
This thing is in multiple files, one that runs everything, second that includes all functions and one that calls all functions
I have tried to define variables inside exec and sure, it works.
I have tried Accessing variables in functions.py(File that contains every function) file and it works too.
I have tried merging functions.py and test.py(the file that's using exec) and then running it directly through python and it worked
My functions.py file
def forloop(current, maximum, code):
for x in range(current, maximum):
exec(str(code), globals())
My 'test.py'(It's the one where I call functions)
from functions import *
name = 'Ameer'
forloop(1,3,"""
echo(name)
""")
And, I am running it all through another exec in my 'runner.py'
from functions import *
file = open('test.py', "r+")
content = file.read()
exec(content)
Now, it's giving me an error saying NameError: name 'name' is not defined when it is defined. Please can you guys help me with this issue
You need to use the variables from the place where forloop is called.
import inspect
def forloop(current, maximum, code):
frame = inspect.currentframe().f_back
for x in range(current, maximum):
exec(str(code), frame.f_globals, frame.f_locals)
I have this code that is throwing an error with exec, and I cant get it to work. It works when
not in a function, though
def hashCheck(data):
exec("hashes = {'hi':'hi'}") #it was a file import before
print(hashes['hi']) #right here is error
try:
return(hashes[data]) #and here is also error
except KeyError:
import hashlib
m = hashlib.md5()
m.update(data)
return(m.hexdigest())
Because your function has no assignments to hashes, python assumes when compiling it that hashes is a global variable. However, when compiling the string for exec, you do have an assignment to hashes so python assumes it is a local variable. So your exec statement assigns to a variable in the local scope, but your print statement looks for it in the global scope.
It may work if you change it to something like:
def hashCheck(data):
hashes = None
exec("hashes = {'hi':'hi'}")
print(hashes['hi'])
That said, you probably shouldn't be using exec() unless you really know what you're doing and are sure you need it. If you just want some human-readable serialization for simple python objects, you may want to look into something like yaml instead.
When I run this code, I get an error that says UnboundLocalError: local variable 'rootent' referenced before assignment.
class calculator():
def __init__(self):
def options():
fetch=float(rootent.get()) #Location of error
if fetch=='1':
def IEntry():
fetch=float(rootent.get())
fetch1=float(rootent1.get())
answer=fetch,'+',fetch1,'=',fetch1+fetch2
ansLabel=Label(root,text=answer).pack()
root=Tk()
root.title('Addition')
root.geometry('450x450+200+200')
rootlabel=Label(root,text='Enter first number').pack()
rootent=Entry()
rootent.pack()
rootlabel1=Label(root,text='Enter second number').pack()
rootent1=Entry()
rootent1.pack()
return
root=Tk()
root.title('Calculator Menu')
root.geometry('450x450+200+200')
rootlabel=Label(root,text='1.Addition').pack()
rootlabel1=Label(root,text='2.Subtraction').pack()
rootlabel2=Label(root,text='3.Multiplication').pack()
rootlabel3=Label(root,text='4.Division').pack()
rootent=Entry(root) #This is what i am trying to input into 'def options()'
rootent.pack()
rootbutton=Button(root,text='Enter option',command=options).pack()
I have tried making rootent global in the function, and I've tried passing it as a para with no luck.
What is wrong, and how do I fix it?
The problem is that python scoping rules are a bit strange. If a function has an assignment to a variable, that variable is assumed local to the function and python won't look in enclosing scopes. In your case, the offending line is rootent=Entry(). your call to rootent.get() is trying to access this rootent variable before it has been assigned. Since you are in python 3.x you can use the nonlocal declaration to make python access the outer scope. Just put nonlocal rootent at the beginning of options() and I think it will work correctly.
There is more discussion of the use of the nonlocal operator here: Python nonlocal statement
Basically, global tells python that the variable name in question resides at the module (file) level. nonlocal tells python to search enclosing scopes for the named variable and use that version, which is more like the behavior you get 'by default' in other languages where you have to explicitly declare all variables.
You are trying to get something from a variable that has not been previously declared. Where is the rootent variable declared in your code?. You need to show us that. It is hard to guess what the type of rootent is.
Thanks for the help, it's now fixed, added nonlocal and changed float(rootent.get()) to rootent.get() and it seemed to fix everything.
The python documentation states "execfile() cannot be used reliably to modify a function’s locals." on the page http://docs.python.org/2/library/functions.html#execfile
Can anyone provide any further details on this statement? The documentation is fairly minimal. The statement seems very contradictory to "If both dictionaries are omitted, the expression is executed in the environment where execfile() is called." which is also in the documentation. Is there a special case when excecfile is used within a function then execfile is then acting similar to a function in that it creates a new scoping level?
If I use execfile in a function such as
def testfun():
execfile('thefile.py',globals())
def testfun2():
print a
and there are objects created by the commands in 'thefile.py' (such as the object 'a'), how do I know if they are going to be local objects to testfun or global objects? So, in the function testfun2, 'a' will appear to be a global? If I omit globals() from the execfile statement, can anyone give a more detailed explanation why objects created by commands in 'thefile.py' are not available to 'testfun'?
In Python, the way names are looked up is highly optimized inside functions. One of the side effects is that the mapping returned by locals() gives you a copy of the local names inside a function, and altering that mapping does not actually influence the function:
def foo():
a = 'spam'
locals()['a'] = 'ham'
print(a) # prints 'spam'
Internally, Python uses the LOAD_FAST opcode to look up the a name in the current frame by index, instead of the slower LOAD_NAME, which would look for a local name (by name), then in the globals() mapping if not found in the first.
The python compiler can only emit LOAD_FAST opcodes for local names that are known at compile time; but if you allow the locals() to directly influence a functions' locals then you cannot know all the local names ahead of time. Nested functions using scoped names (free variables) complicates matters some more.
In Python 2, you can force the compiler to switch off the optimizations and use LOAD_NAME always by using an exec statement in the function:
def foo():
a = 'spam'
exec 'a == a' # a noop, but just the presence of `exec` is important
locals()['a'] = 'ham'
print(a) # prints 'ham'
In Python 3, exec has been replaced by exec() and the work-around is gone. In Python 3 all functions are optimized.
And if you didn't follow all this, that's fine too, but that is why the documentation glosses over this a little. It is all due to an implementation detail of the CPython compiler and interpreter that most Python users do not need to understand; all you need to know that using locals() to change local names in a function does not work, usually.
Locals are kind of weird in Python. Regular locals are generally accessed by index, not by name, in the bytecode (as this is faster), but this means that Python has to know all the local variables at compile time. And that means you can't add new ones at runtime.
Now, if you use exec in a function, in Python 2.x, Python knows not to do this and falls back to the slower method of accessing local variables by name, and you can make new ones programmatically. (This trick was removed in Python 3.) You'd think Python would also do this for execfile(), but it doesn't, because exec is a statement and execfile() is a function call, and the name execfile might not refer to the built-in function at runtime (it can be reassigned, after all).
What will happen in your example function? Well, try it and find out! As the documentation for execfile states, if you don't pass in a locals dict, the dict you pass in as globals will be used. You pass in globals() (your module's real global variables) so if it assigns to a, then a becomes a global.
Now you might try something like this:
def testfun():
execfile('thefile.py')
def testfun2():
print a
return testfun2
exec ""
The exec statement at the end forces testfun() to use the old-style name-based local variables. It doesn't even have to be executed, as it is not here; it just has to be in the function somewhere.
But this doesn't work either, because the name-based locals don't support nesting functions with free variables (a in this case). That functionality also requires Python know all the local variables at function definition time. You can't even define the above function—Python won't let you.
In short, trying to deal with local variables programmatically is a pain and the documentation is correct: execfile() cannot reliably be used to modify a function's locals.
A better solution, probably, is to just import the file as a module. You can do this within the function, then access values in the module the usual way.
def testfun():
import thefile
print thefile.a
If you won't know the name of the file to be imported until runtime, you can use __import__ instead. Also, you may need to modify sys.path to make sure the directory you want to import from is first in the path (and put it back afterward, probably).
You can also just pass in your own dictionary to execfile and afterward, access the variables from the executed file using myVarsDict['a'] and so on.