Structured prog & global variables
Structured prog & global variables
In my ignorance I don't know if this is hardware specific or not. Using an ESP32 spiram.
I have a main program which is getting a little messy, so I have started to use extra files which have function def's in. In the main program I 'import from' so I can use them.
All goes well until I want to manipulate variables which have been declared in the main file. All that I have read indicates that if I declare the variables as 'global' within the external function, before I use them, then they can be accessed.
Well, whatever I do, I get errors thrown up, in that the variable is not recognised.
I would appreciate any guidance here ….. I have done my best in terms of searching … but to no avail.
As a second related question, I have also got a socket (udp) set up in the main program, which retrieves sent data. This all works fine.
In the same 'external' function with the global variable issue, I would like to refer to the socket for sending data out. This also fails.
All works well if I place the function back in the main section, but it would be nice to structure the program in a more orderly fashion.
Thanks for any help.
D.R.
I have a main program which is getting a little messy, so I have started to use extra files which have function def's in. In the main program I 'import from' so I can use them.
All goes well until I want to manipulate variables which have been declared in the main file. All that I have read indicates that if I declare the variables as 'global' within the external function, before I use them, then they can be accessed.
Well, whatever I do, I get errors thrown up, in that the variable is not recognised.
I would appreciate any guidance here ….. I have done my best in terms of searching … but to no avail.
As a second related question, I have also got a socket (udp) set up in the main program, which retrieves sent data. This all works fine.
In the same 'external' function with the global variable issue, I would like to refer to the socket for sending data out. This also fails.
All works well if I place the function back in the main section, but it would be nice to structure the program in a more orderly fashion.
Thanks for any help.
D.R.
-
- Posts: 847
- Joined: Mon Nov 20, 2017 10:18 am
Re: Structured prog & global variables
It is best if possible to avoid global variables where possible.
The cleanest way to have many functions access a common variable is to use a class and then use the prefix self. before any variables that you want to be accessible from all the other functions/methods of the class.
see https://www.tutorialspoint.com/python/p ... bjects.htm
The cleanest way to have many functions access a common variable is to use a class and then use the prefix self. before any variables that you want to be accessible from all the other functions/methods of the class.
see https://www.tutorialspoint.com/python/p ... bjects.htm
Re: Structured prog & global variables
Thank you for that …. still learning.... only a few years to go!
Off to do some reading then.
Thanks again
Off to do some reading then.
Thanks again
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Structured prog & global variables
The advice about avoiding globals is undoubtedly correct. Access is relatively slow. But there are other reasons rooted in general programming practice which you can research online.
It's worth understanding Python's scoping rules. If a module has a global name (whether for data or for an object such as a function) the name's visibility to other modules depends on how the module is imported.
my_module:
The need for a global statement arises if a function needs to modify a global variable. Consider the following
Without the global statement foo() would create a local variable bar and set that to 99 leaving the global bar unchanged: in other words foo() would do nothing useful. For some reason when I was learning Python this took me a while to grasp.
There is an option to import all exposed names from a module with
This should be used with care as it can populate your local namespace with unexpected names and can be a source of evil bugs (say if the author has redefined a Python built-in function). Only use if you understand the module you're importing.
It's worth understanding Python's scoping rules. If a module has a global name (whether for data or for an object such as a function) the name's visibility to other modules depends on how the module is imported.
my_module:
Code: Select all
bar = 42
def foo():
return bar
Code: Select all
import my_module
my_module.foo() # Access by prepending the module name
my_module.bar = 99
print(my_module.foo()) # 99
Code: Select all
from my_module import foo
foo()
bar = 99 # Will create a new variable local to the current module
print(foo()) # Will return 42
Code: Select all
bar = 42
def foo():
global bar
bar = 99
There is an option to import all exposed names from a module with
Code: Select all
from some_module import *
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Structured prog & global variables
Thanks for taking the time ….. these snippets really help get a better understanding ….
Re: Structured prog & global variables
Hello,
We know that using global variables isn't a good practice. But it's sometimes convenient and Python permits it.
However I was recently surprised to find that global variables are global to a module not across all modules. Reading the doc teachs me this is normal behavior. So that's ok when you know it, and one more reason to avoid "global" or at least to be (very) careful.
Exemple tested on Python3 on PC and microPython 1.10 on ESP32
Now we define the same function but in a module:
my_module.py :
We know that using global variables isn't a good practice. But it's sometimes convenient and Python permits it.
However I was recently surprised to find that global variables are global to a module not across all modules. Reading the doc teachs me this is normal behavior. So that's ok when you know it, and one more reason to avoid "global" or at least to be (very) careful.
Exemple tested on Python3 on PC and microPython 1.10 on ESP32
Code: Select all
>>> def foo():
... global bar
... bar = bar + 1
... return bar
...
...
...
>>> bar = 5
>>> foo()
6
>>>
my_module.py :
Code: Select all
def foo():
global bar
bar = bar + 1
return bar
Code: Select all
>>> import my_module
>>> bar = 5
>>> my_module.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "my_module.py", line 3, in foo
NameError: name 'bar' isn't defined
>>>
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Structured prog & global variables
Actually this is a strength of Python. If you issue
you have a guarantee that the only name added to your namespace is my_module: names within the module a guaranteed not to conflict with your own because you have to prepend them with the module name:
Likewise if you issue
you know exactly which names you've added. Issuing
will populate your namespace with an arbitrary assortment of names. This can have unforeseen consequences. It has its uses, but you need to study the module code.
This is the sort of chaos which your truly global variables might unleash
Code: Select all
import my_module
Code: Select all
import my_module
x = my_module.foo()
Code: Select all
from my_module import foo, bar
Code: Select all
from my_module import *
This is the sort of chaos which your truly global variables might unleash
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Structured prog & global variables
Your my_module.py file should rather contain:JumpZero wrote: ↑Thu May 09, 2019 9:15 amNow we define the same function but in a module:
my_module.py :Code: Select all
def foo(): global bar bar = bar + 1 return bar
Code: Select all
>>> import my_module >>> bar = 5 >>> my_module.foo() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "my_module.py", line 3, in foo NameError: name 'bar' isn't defined >>>
Code: Select all
bar = 0
def foo():
global bar
bar = bar + 1
return bar
Code: Select all
>>> import my_module
>>> my_module.bar = 5
>>> my_module.foo()
6
Re: Structured prog & global variables
Hi!
Actually very interesting discussion.
@dhylands you are right the proper way to access the module global variable "bar" is:
"my_module.bar" this avoids confusion, keeping in mind that the main programme global variable "bar" is another variable.
@pythoncoder Yes this is a Python strength: the guarantee of names being uniques in user's namespace when you prepend them with module name. And thanks to pointing out the risks of usingI didn't realize that. Better be careful and use the full name with module name prepending.
And now for the fun: the unleashed sort of chaos
Actually very interesting discussion.
@dhylands you are right the proper way to access the module global variable "bar" is:
"my_module.bar" this avoids confusion, keeping in mind that the main programme global variable "bar" is another variable.
@pythoncoder Yes this is a Python strength: the guarantee of names being uniques in user's namespace when you prepend them with module name. And thanks to pointing out the risks of using
Code: Select all
from module import *
And now for the fun: the unleashed sort of chaos
Code: Select all
jumpzero@penguin:~$ cat my_module.py
bar = 0
def foo():
global bar
bar = bar+1
return bar
jumpzero@penguin:~$ python3
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> bar = 3
>>> bar
3
>>> from my_module import *
>>> bar
0
>>> foo()
1
>>> bar = 7
>>> bar
7
>>> foo()
2
>>> bar
7
>>> foo()
3
>>>