Python Forum
Best way(s) to organize and use "global" values?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Best way(s) to organize and use "global" values?
#1
When writing some applications (e.g., games), one ends up having perhaps dozens or even hundreds of "global" values, of several types:

1. Predefined static values one wishes to use as "named constants"
Example: Index numbers for standard items stored in arrays or lists, or names for color values

2. Values that are static after initialization, perhaps dependent on argument or configuration file or environment variable values
Example: Terminal LINES and COLS values in a console application or a boolean variable for a debug switch argument to optionally generate debugging output

3. Values that are not static for the whole program but which need to be used at many different scoping levels
Example: The current position of a player or other object(s) in a game map

Is it better to use actual python "global" (module-level) variables, or set up a "static_vars" class to initialize and hold them (all or only some?), or some other design pattern that works better?

Thanks in advance for your advice and references.

Peter
Reply
#2
don't use globals unless absolutely necessary
There is no need, pass arguments and use return statements, sooner or later globals will cause you much pain.
Consider the situation where two functions are dependent on a global variable
the program will crash after calling funca:

global hold_count

def funca():
    global hold_count
    hold_count = 'bad news'

def funcb():
    global hold_count

    for i in range(hold_count):        
        print(i) # do something here

    funca()
    print(f"hold_count: {hold_count}")

    for i in range(hold_count):
        print(i)

if __name__ == '__main__':
    hold_count = 10
    funcb()
Output:
0 1 2 3 4 5 6 7 8 9 hold_count: bad news Traceback (most recent call last): File "..../tryme.py", line 21, in <module> funcb() File ".../tryme.py", line 16, in funcb for i in range(hold_count): TypeError: 'str' object cannot be interpreted as an integer
Reply
#3
That is a valid concern, but there are legitimate uses for globals, particularly "named constants".

It isn't reasonable to pass dozens of "global" and/or static variables to functions, so even if one decides to encapsulate them, how would you suggest that organization be accomplished? A global variable class with one instance passed around everywhere? The disadvantage of that solution is that one must then qualify every usage of the variable with the instance name, or use with statements everywhere they are used. And in order not to have to pass that instance in every function call the one instance name would need to be truly global in order for that to work. That seems clumsy to me, but I am only a novice at this language.

Your further advice and/or comments would be appreciated.

Peter
Reply
#4
Maybe you can give code example where you consider using globals is unavoidable.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#5
I think I see the point. With a named constant it may be advantageous from a memory management point of view to define it once. Python itself does similar in the integers -5 to 255.

So, if you are doing a series of calculations using the golden ratio divided by pi. Now, both the golden ratio and pi are defined constants in Python, but rather than doing the calc a bunch of times you might do it once and then save it in a global.

The key here is that the value should be something that is NEVER changed. Otherwise globals will bite you. Hard.
from scipy.constants import golden
from math import pi

global icky
icky = golden/pi 

print(icky)
def fubar() :
    return icky*17
def funbar() :
    return icky*18

print(fubar()*funbar())
Reply
#6
@jefsummers - there is no need of line 4 in this example
IF it is really waranted to have a constant, as per PEP8 recommendation, it should be ALL_CAPS:
Quote:Constants

Constants are usually defined on a module level and written in all capital letters with underscores separating words. Examples include MAX_OVERFLOW and TOTAL.

@pjfarley3, some of your your "examples" under 1 and 2 MAY be a case to use a constant or enumeration. Some of the examples in 1 and 2 are definitely NOT such case - e.g. index numbers for elements in a list (i.e. if you want meaningful names, not int index, work with dict or named tuple). item 3 in the list is exactly why using globals should be avoided - changing variable at different scope levels is recipe for disaster and will cost you a lot of debugging time sooner than later. If we take the example you give - current position of a player, most probably you will have a Player class and it will have current_position attribute if needed, but definitely not a global variable.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#7
Enum's and their derivatives IntEnum, IntFlag and Flag seem to do quite a lot of what I think I need to do, so I will study them carefully.

Is there any syntactic sugar that would permit the names of Enum's and derivatives to be used WITHOUT prefixing the class name?

I just don't see the logic in having to prefix yet another name in front of a name that I define uniquely in the first place.

E.G., if I have an Enum class of "Colors", why do I have to use Colors.RED instead of just RED?

Basically I'm imagining some syntactic construct similar to the Pascal "with" statement which permits structure field names to be used in a block of code without needing to use the structure name as a prefix for them.

I won't be surprised if there is no such "sugar", but a fellow can wish.

Peter
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How do I organize my simple ftp modules? blobdx7 3 451 Jan-05-2024, 01:23 PM
Last Post: Gribouillis
  How can I organize my code according to output that I want ilknurg 1 1,137 Mar-11-2022, 09:24 AM
Last Post: perfringo
Star Split and organize my Pandas Dataframe brunolelli 4 2,635 Apr-18-2021, 03:00 AM
Last Post: brunolelli
  Counting number of words and organize for the bigger frequencies to the small ones. valeriorsneto 1 1,643 Feb-05-2021, 03:49 PM
Last Post: perfringo
  Global variable does not seem to be global. Columbo 6 3,615 Jul-15-2019, 11:00 PM
Last Post: Columbo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020