62

I was reading a question about the Python global statement ( "Python scope" ) and I was remembering about how often I used this statement when I was a Python beginner (I used global a lot) and how, nowadays, years later, I don't use it at all, ever. I even consider it a bit "un-pythonic".

Do you use this statement in Python ? Has your usage of it changed with time ?

Community
  • 1
  • 1
Aurelio Martin Massoni
  • 1,706
  • 3
  • 14
  • 19

12 Answers12

59

I use 'global' in a context such as this:

_cached_result = None
def myComputationallyExpensiveFunction():
    global _cached_result
    if _cached_result:
       return _cached_result

    # ... figure out result

    _cached_result = result
    return result

I use 'global' because it makes sense and is clear to the reader of the function what is happening. I also know there is this pattern, which is equivalent, but places more cognitive load on the reader:

def myComputationallyExpensiveFunction():
    if myComputationallyExpensiveFunction.cache:
        return myComputationallyExpensiveFunction.cache

    # ... figure out result

    myComputationallyExpensiveFunction.cache = result
    return result
myComputationallyExpensiveFunction.cache = None
Jerub
  • 41,746
  • 15
  • 73
  • 90
  • 15
    I tend to use the decorator module's 'memoize' function in instances like this but I can't fault the clarity of your global usage :) – Matthew Trevor Sep 29 '08 at 06:06
  • 6
    I didn't know about the possibility of defining an attribute of a function such as myComputationallyExpensiveFunction.cache and using it inside the function body, thanks! – Aurelio Martin Massoni Sep 29 '08 at 22:32
  • 2
    I had never heard of assigning an attribute to a function, that is great stuff! Thanks! – brad Sep 03 '09 at 02:27
  • 5
    2nd line of 2nd example should be "if getattr(myComputationallyExpensiveFunction, "cache", None):", otherwise AttributeError. – Andy Grover May 24 '12 at 17:50
  • @AndyGrover I didn't need to do that, the code works fine without it and I don't see any AttributeError (?) – AJP Mar 10 '14 at 12:13
15

I've never had a legit use for the statement in any production code in my 3+ years of professional use of Python and over five years as a Python hobbyist. Any state I need to change resides in classes or, if there is some "global" state, it sits in some shared structure like a global cache.

ironfroggy
  • 7,991
  • 7
  • 33
  • 44
  • 1
    Was thinking of using global for the first time specifically for creating a global cache. Your response makes it seem as if you are using something other than the global keyword to create and maintain a global cache... Could you share how you achieved this? – joeyagreco Dec 06 '21 at 00:55
10

I've used it in situations where a function creates or sets variables which will be used globally. Here are some examples:

discretes = 0
def use_discretes():
    #this global statement is a message to the parser to refer 
    #to the globally defined identifier "discretes"
    global discretes
    if using_real_hardware():
        discretes = 1
...

or

file1.py:
    def setup():
        global DISP1, DISP2, DISP3
        DISP1 = grab_handle('display_1')
        DISP2 = grab_handle('display_2')
        DISP3 = grab_handle('display_3')
        ...

file2.py:
    import file1

    file1.setup()
    #file1.DISP1 DOES NOT EXIST until after setup() is called.
    file1.DISP1.resolution = 1024, 768
Adam Rossmiller
  • 101
  • 1
  • 2
8

In my view, as soon as you feel the need to use global variables in a python code, it's a great time to stop for a bit and work on refactoring of your code.
Putting the global in the code and delaying the refactoring process might sound promising if your dead-line is close, but, believe me, you're not gonna go back to this and fix unless you really have to - like your code stopped working for some odd reason, you have to debug it, you encounter some of those global variables and all they do is mess things up.

So, honestly, even it's allowed, I would as much as I can avoid using it. Even if it means a simple classes-build around your piece of code.

kender
  • 85,663
  • 26
  • 103
  • 145
3

Objects are the prefered way of having non-local state, so global is rarely needed. I dont think the upcoming nonlocal modifier is going to be widely used either, I think its mostly there to make lispers stop complaining :-)

JacquesB
  • 41,662
  • 13
  • 71
  • 86
3

I use it for global options with command-line scripts and 'optparse':

my main() parses the arguments and passes those to whatever function does the work of the script... but writes the supplied options to a global 'opts' dictionary.

Shell script options often tweak 'leaf' behavior, and it's inconvenient (and unnecessary) to thread the 'opts' dictionary through every argument list.

Mike McCabe
  • 1,015
  • 9
  • 9
2

Rarely. I've yet to find a use for it at all.

hydrapheetz
  • 3,540
  • 3
  • 17
  • 12
2

It can be useful in threads for sharing state (with locking mechanisms around it).

However, I rarely if ever use it.

Corey Goldberg
  • 59,062
  • 28
  • 129
  • 143
2

I've used it in quick & dirty, single-use scripts to automate some one-time task. Anything bigger than that, or that needs to be reused, and I'll find a more elegant way.

Kena
  • 6,891
  • 5
  • 35
  • 46
1

Once or twice. But it was always good starting point to refactor.

zgoda
  • 12,775
  • 4
  • 37
  • 46
1

I avoid it and we even have a pylint rule that forbids it in our production code. I actually believe it shouldn't even exist at all.

André
  • 12,971
  • 3
  • 33
  • 45
0

If I can avoid it, no. And, to my knowledge, there is always a way to avoid it. But I'm not stating that it's totally useless either