Why is this variable not defined if it is a global variable? - python

I create a list and try to append it to another list, but even though it is a global list it still is not defined.
I had the same issue trying to apppend a string to another list, and that had the same error so I tried to make the string a list.
sees if the player hits
def hit_or_stand():
global hit **<-- notice hit is a global variable**
if hitStand == ("hit"):
player_hand()
card = deck()
hit = []
hit.append(card)
now I need to append hit to pHand (player's hand)
def player_hand():
global pHand
deck()
pHand = []
pHand.append(card)
deck()
pHand.append(card)
pHand.append(hit) **<--- "NameError: name 'hit' is not defined"**
pHand = (" and ").join(pHand)
return (pHand)
hit_or_stand()
player_hand()

global hit
This does not declare a variable which is global. It does not create a variable which does not exist. It simply says "if you see this name in this scope, assume it's global". To "declare" a global variable, you need to give it a value.
# At the top-level
hit = "Whatever"
# Or in a function
global hit
hit = "Whatever"
The only time you need a global declaration is if you want to assign to a global variable inside a function, as the name could be interpreted as local otherwise. For more on globals, see this question.

There is a misunderstanding of the global operation in OP's post. The global inside a function tells python to use that global variable name within that scope. It doesn't make a variable into a global variable by itself.
# this is already a global variable because it's on the top level
g = ''
# in this function, the global variable g is used
def example1():
global g
g = 'this is a global variable'
# in this function, a local variable g is used within the function scope
def example2():
g = 'this is a local variable'
# confirm the logic
example1()
print( g ) # prints "this is a global variable"
example2()
print( g ) # still prints "this is a global variable"

Related

Global variable is not defined - Python and PyGame

i try to create a Flappy Bird clone. When i try to define some Global variables visual studio said me that this variables aren't defined in global scope.
Some could help me??
I tried to move the variables in the global scope and it works, but i don't understand why this solution doesn 't work.
This is my code
Thanks in advance
import pygame
import random
pygame.init()
background = pygame.image.load('img/background.png')
base = pygame.image.load('img/base.png')
bird = pygame.image.load('img/bird.png')
gameover = pygame.image.load('img/gameover.png')
pipe_down = pygame.image.load('img/pipe.png')
pipe_up = pygame.transform.flip(pipe_down, False, True)
windowX = 288
winwowY = 512
frame_rate = 50
display_surface = pygame.display.set_mode((windowX, winwowY))
FPS = frame_rate
pygame.display.set_caption('Flappy Bird')
def drawObject():
display_surface.blit(background, (0, 0))
display_surface.blit(bird, (birdX, birdY))
def update():
pygame.display.update()
pygame.time.Clock().tick(FPS)
# Here is where define my global vars
def initializes():
global birdX, birdY, birdSpeedY
birdX = 60
birdY = 150
birdSpeedY = 0
initializes()
while True:
birdSpeedY += 1
birdY += birdSpeedY
drawObject()
update()
The message is telling you exactly what the issue is. The global variables aren't defined in global scope.
That means that for these variables that you are telling it you want to use from the global namespace global birdX, birdY, birdSpeedY, it expects to find a definition of those in that uppermost namespace. The global keyword does NOT create them in the global namespace just because you use it. They must exist there independent of that.
For them to be defined in the global scope there needs to be an assignment to them in the global namespace, not inside a function or a class. That cannot be something a += either since that is a reference and an assignment and so it assumes that the definition must be elsewhere (or it would be being referenced before a value was assigned).
So somewhere in the global namespace you need an assignment. If you want to handle the initialization in a function (as you are doing) it must still be defined/assigned outside that function, but it can be any value, like None. So you could add this near the top of you program:
birdX = None
birdY = None
birdSpeedY = None
Then still use your initializes() as you are.
Or in your case you would probably just take the stuff inside initializes() and put it at the top /global level.

Are there cases where global keyword is necessary in python?

I want to know if there are some cases where declaring global keyword is necessary in python.
Yes, there are some cases where global is neccessary.
Have a look at this code, which will work fine:
i = 42 # this is a global var
def f():
print(i)
But what if you would like to edit i (which is a global variable).
If you do this, you get an error:
i = 42 # this is a global var
def f():
i += 1 # this will not work
print(i)
We can only access i. If python compiles the function to bytecode it detects an assignment to a variable and it assumes it is a local variable. But this is not the case here (it is a global variable). Therefore if we also want to modify the global var i we must use the global keyword.
i = 42 # this is a global var
def f():
global i
i += 1 # this will change the global var without error
print(i)
When you have shared resources and want to make changes in global one.
a = 0
def add_five():
global a
a += 5
def remove_two():
global a
a -= 2
add_five() # a = 5
add_five() # a = 10
add_five() # a = 15
remove_two() # a = 13

How do I pass a variable between functions python

Here are my two functions:
def selectBadge(a):
curItem = SelectBadgeView.focus()
inter_var = SelectBadgeView.item(curItem)
ListValues = inter_var['values']
print(ListValues)
SelectedBadge.set("Selected Badge: "+str(ListValues[0]))
SelectedBadgeStr=str(ListValues[0])
return SelectedBadgeStr
def selectScout(a,SelectedBadgeStr):
print(a)
if SelectedPatrol.get()==("Selected Patrol: Please Select A Patrol"):
tk.messagebox.showerror("ERROR","Please select a Patrol")
return
if SelectedBadge.get()==("Selected Badge: Please Select A Badge"):
tk.messagebox.showerror("ERROR", "Please select a Badge")
return
print(SelectedBadgeStr)
return
I want to pass the variable SelectedBadgeStr from selectBadge() to selectScout().
The variable a is a internal variable used by the tkinter treeview widget.
a = <ButtonRelease event state=Button1 num=1 x=144 y=39>
I have tried:
return SelectedBadgeStr
However this did not work.
The function is called by:
SelectScoutView.bind('<ButtonRelease-1>', selectScout)
Did you declare SelectedBadgeStr as for example an empty string before defining the function selectBadge(a)?
So just declare it like:
SelectedBadgeStr = ''
def selectBadge(a):
curItem = SelectBadgeView.focus()
.
.
.
It should work.
You can also use a shared global variable:
Declare the variable outside of the functions use:
SelectedBadgeStr = None
At the beginning of the functions use:
global SelectedBadgeStr
Whenever you use the variable now within the functions, you access the global variable

Python Global Variables - Not Defined?

I'm running into an issue where a global variable isn't "remembered" after it's modified in 2 different functions. The variable df is supposed to be a data frame, and it doesn't point to anything until the user loads in the right file. This is similar to something I have (using pandas and tkinter):
global df
class World:
def __init__(self, master):
df = None
....
def load(self):
....
df = pd.read_csv(filepath)
def save(self):
....
df = df.append(...)
save() is always called after load(). Thing is, when I call save(), I get the error that "df is not defined." I thought df got its initial assignment in init(), and then got "updated" in load()? What am I doing wrong here?
You have to use global df inside the function that needs to modify the global variable. Otherwise (if writing to it), you are creating a local scoped variable of the same name inside the function and your changes won't be reflected in the global one.
p = "bla"
def func():
print("print from func:", p) # works, readonly access, prints global one
def func1():
try:
print("print from func:", p) # error, python does not know you mean the global one
p = 22 # because function overrides global with local name
except UnboundLocalError as unb:
print(unb)
def func2():
global p
p = "blubb" # modifies the global p
print(p)
func()
func1()
print(p)
func2()
print(p)
Output:
bla # global
print from func: bla # readonly global
local variable 'p' referenced before assignment # same named local var confusion
bla # global
blubb # changed global
for anyone coming here using python3 - try using nonlocal instead of global - a new construct introduced in python3 which allows you to mutate and read global variables in local scope
You have to use the global keyword inside the function rather than outside. All the df that you have defined inside your function are locally scoped. Here is the right way -
df = pd.DataFrame() # No need to use global here
def __init__(self, master):
global df # declare here
df = None
....
def load(self):
global df # declare here
....
df = pd.read_csv(filepath)
def save(self):
global df # declare here
....
df = df.append(...)

Python alter external variable from within function

When I run this it works, but it says
"name 'select_place' is assigned to before global declaration"
When I get rid of the second global, no comment appears, but as select_place is no longer global it is not readable (if selected) in my last line of code.
I'm really new to python, ideally I'd like a way of not using the global command but after searching i still can't find anything that helps.
My code:
def attempt(x):
if location =='a':
global select_place
select_place = 0
if location =='b'
global select_place
select_place = 1
place = ([a,b,c,d])
This is the start of some turtle graphics
def Draw_piece_a(Top_right):
goto(place[select_place])
You need to declare the variable first, additionally the function code can be made clearer:
select_place = False
def attempt(x):
global select_place
if location == 'a':
select_place = 0
elif location == 'b':
select_place = 1
Also, there is no return value for attempt(), is this what you want?

Categories