0

If you declare a global variable before a function and try to change that variables in a function it throws back an error:

james = 100

def runthis():
    james += 5

This wont work.

Unless you declare the global variables again in the function, like this:

james = 100

def runthis():
    global james
    james += 5

Is there a more simple way to change the variable inside the function? It's sort of messy and annoying re-declaring variables again and again.

  • `global x` seems like a pretty simple way of declaring a variable as global. How would you imagine a simpler way would look like? That said, global variables should be a rare thing to need. I hardly ever use the `global` keyboard. – Sven Marnach Jan 19 '15 at 23:59
  • 1
    You can reference `james` as `globals()['james']` – Anthony Forloney Jan 19 '15 at 23:59
  • Sven Mrnach, well in the instance i'm needing this help for, I find myself having to change global variables in multiple function constantly its sort of a pain. – Python and Android for life Jan 20 '15 at 00:08
  • @user3579419 Well, what I'm saying is -- don't do that. Global state is evil, and using lots of global state results in unmaintainable and untestable code. It's a bit hard to explain this in a few comments here, but it's something every experienced programmer can confirm. – Sven Marnach Jan 20 '15 at 00:11
  • If it serves as a deterrent to using globals, so much the better. – Lee Daniel Crocker Jan 20 '15 at 00:11

2 Answers2

3

Wouldn't it be simpler to avoid using the global variable in the function?

james = 100

def runthis(value):
    return value + 5

james = runthis(james)

If you've got a lot of them it might make more sense to put them in a single mutable container, such as a dictionary:

def runthis(scores):
    scores['james'] += 5

players = {'james': 100, 'sue': 42}

runthis(players)
print players  # -> {'james': 105, 'sue': 42}

If you don't like the scores['james'] notation, you could create a specialized dict class:

# from http://stackoverflow.com/a/15109345/355230
class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self

def runthis(scores):
    scores.james += 5  # note use of dot + attribute name

players = AttrDict({'james': 100, 'sue': 42})

runthis(players)
print players  # -> {'james': 105, 'sue': 42}
martineau
  • 119,623
  • 25
  • 170
  • 301
2

Modifying global variables is ugly in Python. If you need to maintain state, use a class:

class MyClass(object):
    def __init__(self):
        self.james = 100
    def runThis(self):
        self.james += 5

Or, if you need james to be shared among all your instances, make it a class attribute:

class MyClass(object):
    james = 100
    def runThis(self):
        MyClass.james += 5

It may not be simpler, but it is definitely more pythonic.