Reputation: 185
I'm trying to design a counter which would be incremented each time an action is done. Something like this:
def action_on_accounts(self, accounts):
for account in accounts[9:]:
try:
self.browser.get(account)
time.sleep(5)
action_button = self.browser.find_element_by_xpath(u'//button[contains(@class, "Heart")]').click()
counter_var = self.count_actions(counter_var)
print(counter_var)
except selenium.common.exceptions.NoSuchElementException:
break
def count_actions(self, counter_var):
return counter_var + 1
def main(self):
counter_var = 0
(...)
This is throwing a UnboundLocalError: local variable 'counter_var' referenced before assignment
I have read that I have to declare counter_var
as global inside function and did this:
def count_actions(self, counter_var):
global counter_var
return counter_var + 1
It was throwing SyntaxError: name 'counter_var' is parameter and global error
.
So I tried this :
def count_actions(self):
global counter_var
return counter_var + 1
Calling it this way :
counter_var = self.count_actions()
print(counter_var)
And now I have NameError: name 'counter_var' is not defined
....
Please assist
Upvotes: 1
Views: 8375
Reputation: 619
Well if you really want to use a global variable (which I advice against) you can do it with the global
keyword. You need that keyword to declare the variable. Example:
def action_on_accounts():
global counter_var #declare the variable
counter_var = count_actions(counter_var)
print(counter_var)
def count_actions(cv):
global counter_var #you do not have to declare the variable here since we are theoretically in the right scope
print(counter_var) #just to check that is global
return cv + 1 #no need to declare since it is a parameter
if __name__ == "__main__":
counter_var = 0
action_on_accounts() #1
action_on_accounts() #2
print(counter_var) #will return 2
I tested this in the IPython console (Python 3.6).
However I strongly recommend that you use attributes of classes to do the same effect (as in use self not global). Global variables may create bad code.
Upvotes: 1
Reputation: 863
An alternative, simpler solution is to use python's built-in enumerate(); It exists so we don't have to make our own functions. You can then set the count equal to a global variable declared outside your functions
So the code would look like this:
counter_var = 0
def action_on_accounts(self, accounts):
for count, account in enumerate(accounts[9:]):
global counter_var
counter_var = count
print(counter_var)
def main(self):
global counter_var
counter_var = 0
(...)
Upvotes: 4
Reputation: 10590
You should consider defining counter_var
as an attribute: self.counter_var
. It'll be accessible throughout your class (assuming that's what's going on). You won't have to provide it explicitly as an argument in your functions/methods and no need to worry about global variables.
def action_on_accounts(self, accounts):
for account in accounts[9:]:
try:
self.browser.get(account)
time.sleep(5)
action_button = self.browser.find_element_by_xpath(u'//button[contains(@class, "Heart")]').click()
self.count_actions()
print(self.counter_var)
except selenium.common.exceptions.NoSuchElementException:
break
def count_actions(self):
self.counter_var += 1
def main(self):
self.counter_var = 0
(...)
You'll probably want to initialize self.counter_var
with your class however.
Upvotes: 2