I have the following code:
counter = 0
def function_1():
func_2(counter)
def func_2(counter):
func_3(counter)
def func_3(counter):
counter += 1
My goal is to keep track of counter incrementation in func_3() in all other functions.
I tried to make counter global
counter = 0
def function_1():
global counter
func_2(counter)
def func_2(counter):
func_3(counter)
def func_3(counter):
counter += 1
but it does not work, the counter incrementation is just local to func_3()
Any hints?
I tried to find an easy to understand explanation for you, but they all seemed to complicated.
The reason that you are seeing counter as a local variable inside your functions is because you are defining it in the function definition: def func_2(counter):.
To use the global counter inside a function you need to do it like this:
counter = 0
def function_1():
func_2()
def func_2():
func_3()
def func_3():
global counter
counter += 1
You can use globals().update(locals()), example:
counter = 0
def function_1():
func_2()
def func_2():
func_3()
def func_3():
counter += 1
globals().update(locals())
or use global method
counter = 0
def function_1():
func_2()
def func_2():
func_3()
def func_3():
global counter
counter += 1
Related
Hey im having some trouble understanding what I did wrong/finding a way to fix it, can you guys help me?
def main():
Keys = 0
def Function1():
global all
def Function2():
global all
print(str(Keys))
Function2()
Keys = Keys + 1
Function1()
main()
every time i try to run this i get this error "free variable 'Keys' referenced before assignment in enclosing scope"
Thanks in advance!
You need to define global Keys for every function. A function thinks that Keys is a local variable.
def main():
global Keys
Keys = 0
def Function1():
global Keys
global all
def Function2():
global Keys
global all
print(str(Keys))
Function2()
Keys = Keys + 1
Function1()
main()
However, using global is bad. Here are a list of reasons why using global is bad
So, instead of using global, you can pass it as an parametre.
def main():
Keys = 0
def Function1(Keys):
def Function2(Keys):
print(str(Keys))
Function2(Keys)
Keys = Keys + 1
Function1(Keys)
main()
Also, all is a function in python. There is absolutely no need to make it global
I don't know how to effectively word my question, but I'll try my best. I want to be able to use a 'for' statement to iterate through a dictionary and access previously-made 'self' items. Like I said, hard to word the question.
I have found that I can use exec() to do it, but I had been told not to use exec() unless absolutely necessary. Also, I realize what this example does is technically useless, but it's a very simplified version of what I need.
global counter
counter = 0
class GUI:
def __init__(self):
self.stuff = ["foo","bar","fooest","barest"]
for i in self.stuff:
self.process(i)
self.printAll()
def process(self,i):
global counter
counter += 1
self.__dict__.update({"ex{}".format(counter):i})
def printAll(self):
global counter
while counter > 0:
exec("print(self.ex{})".format(counter))
counter -= 1
GUI()
This does work; printAll(self) does print self.ex1 thru ex4. Is there a way to do it without exec()?. Please help!
global counter
counter = 0
class GUI:
def __init__(self):
self.stuff = ["foo","bar","fooest","barest"]
for i in self.stuff:
self.process(i)
self.printAll()
def process(self,i):
global counter
counter += 1
self.__dict__.update({"ex{}".format(counter):i})
def printAll(self):
global counter
while counter > 0:
print(eval("self.ex{}".format(counter)))
counter -= 1
GUI()
I hope this is suitable in your case
For example:
global count
count += 1
#task
def install(hosts, local_swift_config):
env.use_ssh_config = True
env.hosts = set_hosts(hosts)
execute(place_count)
def place_count():
sudo('echo {} > /home/user/some_count'.format(count))
count += 1
It doesn't have to be a global, what is the preferred way to do this with fabric?
count = 0
#task
def install(hosts, local_swift_config):
env.use_ssh_config = True
env.hosts = set_hosts(hosts)
execute(place_count)
def place_count():
sudo('echo {} > /home/user/some_count'.format(count))
global count
count += 1
I've had this work for simple functions in fabric. Your problem is with python globals, not fabric.
See this thread for more information on globals: Stacokverflow Python Globals
I decided not to use global:
def counter():
env.count += 1
if env.count == 2:
env.count += 4
#task
def install(hosts):
env.count = 0
execute(counter)
print(env.count)
execute(counter)
print(env.count)
execute(counter)
print(env.count)
Ouput:
1
6
7
Done.
I am trying to make a variable in Python go up by one continuously, but inside a function. What I am using is something like this:
def func1():
def set1():
x=5
y=10
##lots of code
x+=1
y+=1
def func2():
while True:
func1()
set1()
func2()
I'm wondering if there is a much better way to do this?
Probably the best way to do this is to put the definition of x and y into function 2, and have them be inputs and outputs of function 1.
def func1(x, y):
##lots of code
x+=1
y+=1
return x, y
def func2():
x = 5
y = 10
while True:
x, y = func1(x, y)
Other alternatives include defining x and y globally and using global x, global y or using mutable default arguments to make the function retain state, but generally better to not resort to these options if you don't have to.
A bit of code review and recommendations:
def func1():
def set1():
x=5
y=10
##lots of code
x+=1
y+=1
def func2():
while True:
func1()
set1() # This won't work because set1 is in the local scope of func1
# and hidden from the global scope
func2()
Looks like you want the function to count each time it is called. May I suggest something like this?:
x=5
y=10
def func1():
global x, y
x+=1
y+=1
print x, y
def func2():
while True:
func1()
func2()
Better than using a global variable, stick them in a mutable object in a nested scope:
Counts = dict(x=5, y=10)
def func1():
Counts['x'] += 1
Counts['y'] += 1
print Counts['x'], Counts['y']
def func2():
while True:
func1()
func2()
x = None
y = None
def set1():
global x, y
x=5
y=10
def func1():
global x, y
x+=1
y+=1
def func2():
while True:
func1()
set1()
func2()
** just saw the edit on going up instead of down - modified code to suit**
It's hard to tell from your question what your actual use case is but I think a Python generator may be the right solution for you.
def generator(x, y):
yield x,y
x += 1
y += 1
Then to use:
if __name__ == "__main__":
my_gen = generator(10,5)
for x,y in my_gen:
print x,y
if x+y > 666:
break
This may be a slightly advanced for someone new to Python. You can read up on generators here: http://anandology.com/python-practice-book/iterators.html
First of all, the set1 function doesn't seem to do much at all, so you could take it away.
If you want to keep count of the number of calls or keep state between calls, the best, more readable way is to keep this inside an object:
class State(object):
def __init__(self):
self._call_count = 0
self.x = 5
def func1(self):
self._call_count += 1
self.x = ... Whatever
def func2():
state = State()
while True:
state.func1()
In Python, is there a way to assign different decorators to functions as variables?
For example (the following code doesn't execute, obviously):
def status_display(function):
def body():
print("Entering", function.__name__)
function()
print("Exited", function.__name__)
return body
def call_counter(function):
counter = 0
def body():
function()
nonlocal counter
counter += 1
print(function.__name__, 'had been executed', counter, 'times')
return body
def a_function():
print('a_function executes')
# problems start here
# is there a working alternative to this false syntax?
#status_display
a_function_with_status_display = a_function()
#call_counter
a_function_with_call_counter = a_function()
# for an even crazier feat
# I knew this wouldn't work even before executing it
a_function_with_status_display = #status_display a_function()
a_function_with_call_counter = #call_counter a_function()
Thanks in advance.
a_function_with_status_display = status_display(a_function)
a_function_with_call_counter = call_counter(a_function)
You seem to be able to write decorators, but you don't know what they do?