I am trying to run following code in Python3.4, but I am getting error.
def checknumner():
i = 0
print("checknumber called...")
def is_even():
print("is_even called...")
global i
if i % 2 == 0:
print("Even: ", i)
else:
print("Odd: ", i)
i += 1
return is_even
c = checknumner()
print(c())
print(c())
print(c())
I am not able to access variable "i" in sub function.
When I comment out "global i" statment
D:\Study\Python>python generator_without_generator.py checknumber called... is_even called... Traceback (most recent call last): File "generator_without_generator.py", line 24, in <module>
print(c()) File "generator_without_generator.py", line 16, in is_even
if i % 2 == 0: UnboundLocalError: local variable 'i' referenced before assignment
When I add "global i" statment
D:\Study\Python>python generator_without_generator.py checknumber called... is_even called... Traceback (most recent call last): File "generator_without_generator.py", line 24, in <module>
print(c()) File "generator_without_generator.py", line 16, in is_even
if i % 2 == 0: NameError: name 'i' is not defined
Can anyone please explain this?
If you're using Python 3 (and it looks like you are), there's an amazing way to tackle this issue:
def function():
i = 0
def another_function():
nonlocal i
# use 'i' here
Here, i isn't global as it would've been defined outside both functions otherwise. It also isn't local to another_function as it's defined outside it. So, it's non local.
More info about nonlocal:
Python nonlocal statement
Python 3.6 docs
Quick guide about nonlocal in Python 3
Related
I tried using the python help() function to preview the docstring of a function I created but the terminal keeps saying "NameError: name 'functionName' is not defined".
I tried passing parameters into my function but nothing's helped.
def coefficients():
""" Evaluates value of inputs and determines use case for almighty formula function """
def coefficient_of_xsquared():
if a == "" or a == 0 or a == " ":
print (error)
return a
coefficient_of_xsquared()
def coefficient_of_x():
if b == "" or b == 0 or b == " ":
print (error)
return b
coefficient_of_x()
def coefficient_of_one():
if c == "" or c == 0 or c == " ":
print (error)
return c
coefficient_of_one()
Expected: Evaluates value of inputs and determines use case for almighty formula function
Actual:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'coefficients' is not defined
It sounds like the function isn't defined when you are trying to call help.
If the function is defined in a file (e.g. modulename.py), you need to import it into the interactive interpreter before you can use it. If the files is called MODULENAME.py, use from MODULENAME import coefficients before you try to use it.
AMOUNT = 1
x = 175
y = 175
def main():
screen = pygame.display.set_mode((600,600))
screen.fill( (251,251,251) )
BoxAmountCalc(humaninput)
DrawBoxCalc()
pygame.display.flip()
while True:
for event in pygame.event.get():
if event.type == QUIT:
return
def BoxAmountCalc(x):
x = (2**humaninput) * (2**humaninput)
size = 600/x
return size
def DrawBoxCalc():
while True:
pygame.draw.rect(screen,(0,0,0), (x,y,size,size))
AMOUNT += 1
x = x + size
x = y + size
pygame.display.flip()
if AMOUNT > humaninput:
break
I've left out a few parts of the code, some of the variable definitions, but when I try to run this code it gives me an error saying that "screen" is not defined.
Is this because I need it to be defined as a parameter for the function and then pass it into the function, or am I missing something completely here?
Thank you for looking, I'm sorry for a very beginner question.
Is this because I need it to be defined as a parameter for the
function and then pass it into the function.
Yes. Once a function finishes executing, the variables created therein are destroyed. Here is an example:
def go():
x = 10
go()
print(x)
--output:--
Traceback (most recent call last):
File "1.py", line 5, in <module>
print(x)
NameError: name 'x' is not defined
Same thing here:
def go():
x = 10
def stay():
print(x)
go()
stay()
--output:--
File "1.py", line 9, in <module>
stay()
File "1.py", line 6, in stay
print(x)
NameError: name 'x' is not defined
But:
x = 10
def go():
print(x)
go()
--output:--
10
And better:
def go(z):
print(z)
x = 10
go(x)
--output:--
10
Try to keep your functions self contained, which means they should accept some input and produce some output without using variables outside the function.
In your code, you can do:
DrawBoxCalc(screen) and def DrawBoxCalc(screen):
but you also have an issue with humaninput. I would try to define DrawBoxCalc as DrawBoxCalc(humaninput, screen), and call it with both args. That means you will have to define main as main(humaninput).
Also, function names should start with a lower case letter, and python uses what is called snake_case for lower case names, so draw_box_calc, and class names should start with a capital letter and they can use camel case: class MyBox.
I'm writing a Python 3.6 script that works with Tkinter and an SQLite 3 database, but I get this error:
if "fImage" in globals() and not(fImage==None):
UnboundLocalError: local variable 'fImage' referenced before assignment
The interested code is this:
from tkinter import *
from ttk import *
from tkinter import Toplevel, Tk
import sqlite3 as sql
def Salvataggio(mode,nome,cognome,sitoweb,email,idx):
conn=sql.connect(os.path.join(path, fn_prof),isolation_level=None)
c=conn.cursor()
if mode=="add":
if "fImage" in globals() and not(fImage==None):
c.execute("INSERT INTO prof VALUES ('{}','{}','{}','{}','{}','{}')".format(len(prof.keys())+1,nome.get(),cognome.get(),fImage,sitoweb.get(),email.get()))
else:
c.execute("INSERT INTO prof VALUES ('{}','{}','{}','{}','{}','{}')".format(len(prof.keys())+1,nome.get(),cognome.get(),"",sitoweb.get(),email.get()))
del fImage
wa.destroy()
elif mode=="edit":
if "fImage" in globals() and not(fImage==None):
c.execute("""UPDATE prof
SET nome = '{}', cognome = '{}', imageURI='{}', web='{}', email='{}'
WHERE ID={}; """.format(nome.get(),cognome.get(),fImage,sitoweb.get(),email.get(),idx))
else:
c.execute("""UPDATE prof
SET nome = '{}', cognome = '{}', web='{}', email='{}'
WHERE ID={}; """.format(nome.get(),cognome.get(),sitoweb.get(),email.get(),idx))
del fImage
def selImmagine(bi):
if not("fImage" in globals()):
global fImage
fImage=askopenfilename(filetypes=[(_("File Immagini"),"*.jpg *.jpeg *.png *.bmp *.gif *.psd *.tif *.tiff *.xbm *.xpm *.pgm *.ppm")])
# other code...
Do you know how to solve this? The error results with the if and the elif in the salvataggio() function.
Thanks
Remove:
del fImage
parts, it tries to remove fImage whether or not it exists.
See below Minimal, Complete, and Verifiable example:
def func():
del variable_that_never_existed
func()
The proximal cause of your error is:
del fImage
which works like assignment, it causes fimage to be treated as local. Therefore, you are getting an unbound-local error, which makes sense, since you never assign to fImage in the first place in Salvataggio
Anyway, yours is a special case of the typical UnboundLocalError, because it didn't involve assignment to the variable to make it get marked as local. A common cause being a hidden assignment:
You get a plain name error if the variable is neither global nor local.
In [1]: def f():
...: if x in {}:
...: pass
...:
In [2]: f()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-2-0ec059b9bfe1> in <module>()
----> 1 f()
<ipython-input-1-80c063ba8db6> in f()
1 def f():
----> 2 if x in {}:
3 pass
4
NameError: name 'x' is not defined
However, the del marks the name as local:
In [3]: def f():
...: if x in {}:
...: pass
...: del x
...:
In [4]: f()
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-4-0ec059b9bfe1> in <module>()
----> 1 f()
<ipython-input-3-5453b3a29937> in f()
1 def f():
----> 2 if x in {}:
3 pass
4 del x
5
UnboundLocalError: local variable 'x' referenced before assignment
This is why your check:
if "fImage" in globals() and not(fImage==None):
is the line where it fails. I do not understand why you always are checking whether fimage is in globals(). Note, 'fimage' in globals() can be true while fimage is a local name... hence the unbound local.
comodin.py
def name():
x = "car"
comodin_1.py
import comodin
print comodin.x
Error:
Traceback (most recent call last):
File "./comodin_2.py", line 4, in <module>
print comodin.x
AttributeError: 'module' object has no attribute 'x'
Is this possible?
In the code you wrote, "x" doesn't exist in "comodin". "x" belongs to the function name() and comodin can't see it.
If you want to access a variable like this, you have to define it at the module scope (not the function scope).
In comodin.py:
x = "car"
def name():
return x
In comodin_1.py:
import comodin
print comodin.name()
print comodin.x
The last 2 lines will print the same thing. The first will execute the name() function and print it's return value, the second just prints the value of x because it's a module variable.
There's a catch: you have to use the 'global' statement if you want to edit the value "x" from a function (add this at the end of comodin.py):
def modify_x_wrong():
x = "nope"
def modify_x():
global x
x = "apple"
And in comodin_1.py:
print comodin.name() # prints "car"
comodin.modify_x_wrong()
print comodin.name() # prints "car", once again
comodin.modify_x()
print comodin.name() # prints "apple"
The code is from the guide of pyquery
from pyquery import PyQuery
d = PyQuery('<p class="hello">Hi</p><p>Bye</p>')
d('p').filter(lambda i: PyQuery(this).text() == 'Hi')
My question is this in the 3rd line is an unbound variable and is never defined in current environment, but the above code still works.
How can it work? Why it doesn't complain NameError: name 'this' is not defined?
It seems that something happens at https://bitbucket.org/olauzanne/pyquery/src/c148e4445f49/pyquery/pyquery.py#cl-478 , could anybody explain it?
This is done via Python's func_globals magic, which is
A reference to the dictionary that holds the function’s global variables — the global namespace of the module in which the function was defined.
If you dive into PyQuery code:
def func_globals(f):
return f.__globals__ if PY3k else f.func_globals
def filter(self, selector):
if not hasattr(selector, '__call__'):
return self._filter_only(selector, self)
else:
elements = []
try:
for i, this in enumerate(self):
# The magic happens here
func_globals(selector)['this'] = this
if callback(selector, i):
elements.append(this)
finally:
f_globals = func_globals(selector)
if 'this' in f_globals:
del f_globals['this']
return self.__class__(elements, **dict(parent=self))
Others have correctly point out how this is defined inside that lambda you are talking about.
To elaborate a bit more, try out the following code:
>>> def f():
... print f_global
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
NameError: global name 'f_global' is not defined
>>> f.__globals__['f_global'] = "whoa!!" #Modify f()'s globals.
>>> f()
whoa!!
This is exactly what is happening there. On line 496, you would see the following code:
for i, this in enumerate(self): #this is the current object/node.
func_globals(selector)['this'] = this #func_globals returns selector.__globals__
This doesn't throw a NameError because the variable might exist at the time the actual function is called.
>>> f = lambda i: some_non_named_var
>>> f(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <lambda>
NameError: global name 'some_non_named_var' is not defined
The above does not error until you call the function that you've stashed away. In the example code you showed, they are manually setting a variable called this in the func_globals before calling the lambda selector function.