# Modifying variable outside of function

**URL:** <https://discuss.python.org/t/modifying-variable-outside-of-function/73049>\
**Category:** Python Help\
**Created:** [December 2, 2024, 12:30pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049 "2024-12-02T12:30:35Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![muekno](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/muekno/32/26317_2.png) [@muekno](https://discuss.python.org/u/muekno)\
**Post date:** [December 2, 2024, 12:30pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/1 "2024-12-02T12:30:35Z")

</div>

Think its a beginner question, but I do not understand why

```python
# some lines of working code
minval = 10
maxval =22
test = 0 # a new added variable

def a_function():
    # some lines of working code
    test +=1 # new code line
    # some lines of working code
# more lines of working
a_function()
# more working code 

```

now the problem in the test +=1 line show Unresolved reference ‘test’

while I can use, at least reading, other variables in functions

Where am I wrong  
Thanks for help  
Regards  
Rainer

---

<div class="post-metadata">

**Author:** ![petercordia](https://avatars.discourse-cdn.com/v4/letter/p/bb73d2/32.png) [@petercordia](https://discuss.python.org/u/petercordia)\
**Post date:** [December 2, 2024, 12:42pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/2 "2024-12-02T12:42:12Z")

</div>

```python
# some lines of working code
minval = 10
maxval =22
test = 0 # a new added variable

def a_function():
    global test
    # some lines of working code
    test +=1 # new code line
    # some lines of working code
# more lines of working
a_function()
# more working code 

```

but please please don’t do this.  
It’s horrid. Function side effects are horrid.

Just use the pattern (with explicit assignment)

```python
test = 0

def f(test):
  return test + 1

test = f(test)

```

instead

---

<div class="post-metadata">

**Author:** ![Rosuav](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rosuav/32/3429_2.png) [@Rosuav](https://discuss.python.org/u/Rosuav)\
**Post date:** [December 2, 2024, 1:09pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/3 "2024-12-02T13:09:25Z")

</div>

> [@petercordia](#):
>
> but please please don’t do this.  
> It’s horrid. Function side effects are horrid.

That’s a bit overblown. Globals have their place.

The `global` statement is exactly what the OP wants here.

---

<div class="post-metadata">

**Author:** ![muekno](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/muekno/32/26317_2.png) [@muekno](https://discuss.python.org/u/muekno)\
**Post date:** [December 2, 2024, 1:32pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/4 "2024-12-02T13:32:53Z")

</div>

I understand what Peter means, but that would not work, the variable ist outside any function. In fact I have a form with a lot of field and before the writing the values to a database the input is checked and everywhere an invalid input foud the variable should be incremeted, beforewriting to the databae the varible is checked an no writing if greater than zero and the focus is set back to the first invalid form field.

So what Chris means is OK. Do I have do define the variable a global an how

Regards  
Rainer

---

<div class="post-metadata">

**Author:** ![Quercus](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/quercus/32/31483_2.png) [@Quercus](https://discuss.python.org/u/Quercus)\
**Post date:** [December 2, 2024, 1:39pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/5 "2024-12-02T13:39:20Z")

</div>

This is considered to be an assignment statement, and since `test` was not declared as `global` inside the function, the name `test` becomes local throughout the function:

```
    test +=1 # new code line

```

Then, since `test` had not been given a value within the function prior to that attempted update, we have an `Unresolved reference`. We cannot update the value of a variable when the variable does not have a value.

See [What are the rules for local and global variables in Python?](https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python) for additional information.

---

<div class="post-metadata">

**Author:** ![petercordia](https://avatars.discourse-cdn.com/v4/letter/p/bb73d2/32.png) [@petercordia](https://discuss.python.org/u/petercordia)\
**Post date:** [December 2, 2024, 1:42pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/6 "2024-12-02T13:42:42Z")

</div>

That sounds like the kind of situation where I would say “please don’t use a global”.

I do agree with @Rosuav insofar as there exist situations where it would be permissible to use a global. Quick-and-dirty debugging comes to mind, because implementing a global counter is faster than putting a proper counter decorator onto a function.

But for a beginner especially, using globals allows you to hold onto poor code patterns, where a bit of dogmatic “No globals allows” mentality would push you to discover cleaner code patterns.

For what you’re describing, if I’m following it correctly, I would use a function that evaluates a form and returns one of

- N errors found, first field with error is: …
- 0 errors found, None

and after that proceed with either setting the focus or writing to the database.

One advantage is that since you don’t have a global state, you can’t forget to set/reset the global state.

---

<div class="post-metadata">

**Author:** ![Quercus](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/quercus/32/31483_2.png) [@Quercus](https://discuss.python.org/u/Quercus)\
**Post date:** [December 2, 2024, 1:51pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/7 "2024-12-02T13:51:53Z")

</div>

> [@Quercus](#):
>
> We cannot update the value of a variable when the variable does not have a value.

To clarify, “update” is used here to mean utilizing one of the enhanced assignment operators, such as `+=`.

---

<div class="post-metadata">

**Author:** ![muekno](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/muekno/32/26317_2.png) [@muekno](https://discuss.python.org/u/muekno)\
**Post date:** [December 2, 2024, 2:13pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/8 "2024-12-02T14:13:14Z")

</div>

OK I am no beginner in programming, I do that since 50years, Assembler, PHP, C++ and others and I am not a real beginner in Python, but I new in Python GUI programming.  
To Clear what I want, I have that form, each field has its validate function you can press the save button at any time, so to make it easy, before writing I call al the validate function one after the other and the I will know if everything is ok or if there still an invalid field, by klicking “save” by the user before all fields are valid.  
So I thought incrementing a counter will the easiest way to do this.  
Regards  
Rainer

---

<div class="post-metadata">

**Author:** ![muekno](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/muekno/32/26317_2.png) [@muekno](https://discuss.python.org/u/muekno)\
**Post date:** [December 2, 2024, 3:00pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/9 "2024-12-02T15:00:29Z")

</div>

Modified my code, but test is not changed even if it should  
be aware this is just a minimized example

```python
# some lines of working code
minval = 10
maxval =22
test = 0 # a new added variable

def a_function():
     gobal test
    # some lines of working code
    test +=1 # new code line
    # some lines of working code
# more lines of working
a_function()
# more working code 

```

But test is not changed

---

<div class="post-metadata">

**Author:** ![muekno](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/muekno/32/26317_2.png) [@muekno](https://discuss.python.org/u/muekno)\
**Post date:** [December 2, 2024, 3:04pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/10 "2024-12-02T15:04:32Z")

</div>

I modified my code, be aware this i just a minimized exable

```python
# some lines of working code
minval = 10
maxval =22
global test = 0 # a new added variable

def a_function():
     global test
    # some lines of working code
    test +=1 # new code line
    # some lines of working code
# more lines of working
a_function()
# more working code 

```

No more errors but test does not change  
Regards  
Rainer

---

<div class="post-metadata">

**Author:** ![Mholscher](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/mholscher/32/15325_2.png) [@Mholscher](https://discuss.python.org/u/Mholscher)\
**Post date:** [December 2, 2024, 3:14pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/11 "2024-12-02T15:14:50Z")

</div>

The text you showed, throws a syntax error. It is not what you were running.

```python
(venv) mennoh@vecht12-2:~/python/test1> python glcount.py
  File "/home/mennoh/python/test1/glcount.py", line 4
    global test = 0 # a new added variable
                ^
SyntaxError: invalid syntax

```

I changed it to:

```python

# some lines of working code
minval = 10
maxval =22
test = 0 # a new added variable

print(test)

def a_function():
    global test
    # some lines of working code
    test +=1 # new code line
    # some lines of working code
# more lines of working
a_function()
print(test)
# more working code

```

Which gave me as output:

```python
(venv) mennoh@vecht12-2:~/python/test1> python glcount.py
0
1

```

So that works.

---

<div class="post-metadata">

**Author:** ![petercordia](https://avatars.discourse-cdn.com/v4/letter/p/bb73d2/32.png) [@petercordia](https://discuss.python.org/u/petercordia)\
**Post date:** [December 2, 2024, 3:47pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/12 "2024-12-02T15:47:51Z")

</div>

Sorry to insult you, if you perceived it that way. I know I sometimes use an unfortunate word choice.

The code posted by @Mholscher and me shows how it should work with global variables. (You use global to pull a variable into a function, not when you declare the function globally.)

If you have 50 years of experience you may just want a quick way to do what you’d do in Assembler, which is fine.  
There are more pythonic ways to achieve the same, without a global counter.  
Specifically by using a list-, dict- or generator- comprehension. If you have a sequence of functions, python makes it very easy to test whether any of them return True, what the sum is of their returns (or how many of them return True), and what the first function is that matches a condition (such as returning True).  
Such a solution would be easier for me to debug, when you run into trouble like you apparently did.  
But to each their own.

---

<div class="post-metadata">

**Author:** ![muekno](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/muekno/32/26317_2.png) [@muekno](https://discuss.python.org/u/muekno)\
**Post date:** [December 2, 2024, 4:20pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/13 "2024-12-02T16:20:19Z")

</div>

First thanks for help.  
Assembler ist 40 years away, but what I Iearned the last weeks, that Python is lot different from C++, even if there are a lot of C++ things work in Python too i.e. If … then …, or or for loops etc. but are going in Python more elegant and easy. Other C++ thing are not working im Python but have equivalents in Python. So please excuse. I think someone new in programming will have i easier to learn Python than some who is coming from an other language  
Regards  
Rainer

---

<div class="post-metadata">

**Author:** ![da-dada](https://avatars.discourse-cdn.com/v4/letter/d/8491ac/32.png) [@da-dada](https://discuss.python.org/u/da-dada)\
**Post date:** [December 2, 2024, 9:15pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/14 "2024-12-02T21:15:36Z")

</div>

> [@petercordia](#):
>
> there exist situations where it would be permissible to use a global

have you got a compelling example for a writable global varible except for quick-and dirty 🫢

---

<div class="post-metadata">

**Author:** ![AlSweigart](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/alsweigart/32/12237_2.png) [@AlSweigart](https://discuss.python.org/u/AlSweigart)\
**Post date:** [December 2, 2024, 9:49pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/15 "2024-12-02T21:49:09Z")

</div>

You could fix this and make it work the way you want by adding a `global` statement:

```python
test = 0 # a new added variable

def a_function():
    global test 
    test +=1 # new code line

```

This makes `test` a global variable that is accessible from anywhere in the program, whereas by default `test` would be considered a local variable.

The nice thing about functions is that they isolate a part of your program: you only have to bother about the inputs (the arguments assigned to the parameters in the function call) and the outputs (the return value). So if you have a bug with the output, you know the source of the bug has to be somewhere inside the function.

You _can_ use global variables, and for small programs they’re fine. The reason experienced software developers will tell you not to use them is that if you use a global variable in the function and there’s a bug, then the source of the bug could be that global variable having a weird/wrong value in it. And since it’s global, the variable could have gotten that weird/wrong value from _anywhere_ in the program.

This isn’t a big deal when your programs are small, but if your program is hundreds of thousands of lines long, that’s a lot of ground to cover to trace where the weird/wrong value came from.

My policy is for beginners to go ahead and use global variables when you’re starting out with small programs. You’ll eventually start coming across cases where using them is less than ideal, and you’ll see when and why you shouldn’t use them from your own experience.

---

<div class="post-metadata">

**Author:** ![muekno](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/muekno/32/26317_2.png) [@muekno](https://discuss.python.org/u/muekno)\
**Post date:** [December 3, 2024, 6:14am UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/16 "2024-12-03T06:14:54Z")

</div>

Thank you for your help that made me fix my problem. And thank you for all your explanations.  
An the other hand I think I have enough experiance to know the pros, cons and risks of global variables. In this case the global is if not = 0 an error sign, being set by quite a lot of validating functions, checked by other functions to proceed the program or return to input GUI, to let the user correct his input. I think thats a good reason to do this with a global. If there is a better way in Python without the global, let me know. I have not enough Python programming experience to imagine a better solution.

Regards  
Rainer

---

<div class="post-metadata">

**Author:** ![petercordia](https://avatars.discourse-cdn.com/v4/letter/p/bb73d2/32.png) [@petercordia](https://discuss.python.org/u/petercordia)\
**Post date:** [December 3, 2024, 7:34am UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/17 "2024-12-03T07:34:02Z")

</div>

The debugger is often a global mutable object, and I think there is a compelling case for that.  
But I can’t currently conceive of a situation where I would leave a writable global variable in a merge request.

---

<div class="post-metadata">

**Author:** ![petercordia](https://avatars.discourse-cdn.com/v4/letter/p/bb73d2/32.png) [@petercordia](https://discuss.python.org/u/petercordia)\
**Post date:** [December 3, 2024, 7:43am UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/18 "2024-12-03T07:43:15Z")

</div>

If you have a list of validating functions, and you could store them in a dictionary for example, you could use a pattern like

```python
failed_fields = [field_name if not validator[field_name]()]
num_failed_fields = len(failed_fields)
if failed_fields:
  first_failed_field = failed_fields[0]

```

or

```python
a_field_failed = not all(valid() for valid in validators)

```

It depends on how you have organised your form, the values in the fields, and the validators. If you could specify what you’re working with I could perhaps suggest a specific solution.

---

<div class="post-metadata">

**Author:** ![da-dada](https://avatars.discourse-cdn.com/v4/letter/d/8491ac/32.png) [@da-dada](https://discuss.python.org/u/da-dada)\
**Post date:** [December 3, 2024, 6:40pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/19 "2024-12-03T18:40:17Z")

</div>

> [@muekno](#):
>
> In this case the global is if not = 0 an error sign, being set by quite a lot of validating functions, checked by other functions to proceed the program or return to input GUI, to let the user correct his input

I could imaging a misanderstanding of the GUI workings  
**in case of an error** only the user must be informed via the GUI, and best cursor (focus) and message are at the faulty entry  
and this must be done **every time** before saving (GUI locked of course, some transaction behaviour)  
(there may be _modified flags_ at the fields and _Validators_ in the GUI, for performance)  
so there is no need at all to remember a GUI input error, I think 🤣

---

<div class="post-metadata">

**Author:** ![muekno](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/muekno/32/26317_2.png) [@muekno](https://discuss.python.org/u/muekno)\
**Post date:** [December 3, 2024, 8:58pm UTC](https://discuss.python.org/t/modifying-variable-outside-of-function/73049/20 "2024-12-03T20:58:42Z")

</div>

OK there are three field mandatory name(min 3 max 40 chars), password (min 6, max 30), email (nin 4, max 40 +a valid email) mandatory, an the optional fields age betwen 10 and 99, gender m/f/o and address max 40 chars.  
each fiel has ist own check function, and a user info field whats wrong or OK, as long the conditon is ok, the cursor is set back into the field. I did not manage it to disable the save button while not every filed is valid in case of the optional fields.  
So it is posible to click the save button any time independent.  
My solution was when save is clicked to set the global test var to 0, call every check function on after the other and if an error is found set the cursor back in the field, notifying the user and increment the test var, So if all field s avalid the test var ist still zero and I can insert everything into a database. If it ist not 0, the user is back in the form, noticed whats still wrong, Thats go es as long as not every field is valid.  
I everything is valid, the data are saved to the database, the form is cleared, the focus set ti the firts field. That work fine now. My only problem was makeing the global work and now a big discussion came out of it. If someone is interested in the complete code, let me know, I will post it here

Regards  
RAiner

[Next page](https://discuss.python.org/t/modifying-variable-outside-of-function/73049.md?page=2)
