50

I'm using functions so that my program won't be a mess but I don't know how to make a local variable into global.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • 1
    If you use functions, but make their variables global, you haven't actually gained much ;-) –  Dec 27 '12 at 08:57
  • 5
    *"I'm using functions so that my program won't be a mess"*, so **just don't** and refactor your code so that you wont need them. – Rik Poggi Dec 27 '12 at 08:58
  • No, I will not make all their variables global, probably just a few. –  Dec 27 '12 at 08:58
  • 3
    So what? Still neither necessary nor good. Use return values and parameters. –  Dec 27 '12 at 09:00
  • @mgisnobr, I'm doing opposite, I'm going to use local variables in the main program, not just the functions –  Dec 27 '12 at 09:01
  • I set up the variables in the function's parameters and the function changes them and I have to use them back in the main loop. I return the values but can't assign them to a variable. –  Dec 27 '12 at 09:03
  • It's okay to use global variables, but making a local variable as global is odd. Just make it global once and for all. At the end of the time, your code can be import and is part of some global environment. Security wise, I don't really see anything wrong with using a plain global. – CppLearner Dec 27 '12 at 09:03
  • 2
    Can you give us a short example of how you'd be using global values? (Edit your question) We might be able to suggest a better approach. – Alex L Dec 27 '12 at 09:04
  • @HwangYouJin What do you mean you can't assign them back to a variable? – CppLearner Dec 27 '12 at 09:04
  • Yes, I can't. Since when I return the value, the global variable does not change its value –  Dec 27 '12 at 09:14
  • Thank you guys, already found a solution, I mean I found another way so that I will not need this anymore. How do you close a question? –  Dec 27 '12 at 14:44
  • @HwangYouJin You should accept the answer that helped you the most :) Keep on asking questions and playing with Python, you're doing much better than most 13 year olds! (Boo to the downvoters) – Alex L Dec 28 '12 at 02:17
  • Oh, so you checked my profile. Well, you know I'm already 14 now, but then OK, I'll check the answer that made me learn something, or well, you know. –  Dec 28 '12 at 05:19

5 Answers5

39

Here are two methods to achieve the same thing:

Using parameters and return (recommended)

def other_function(parameter):
    return parameter + 5

def main_function():
    x = 10
    print(x)    
    x = other_function(x)
    print(x)

When you run main_function, you'll get the following output

>>> 10
>>> 15

Using globals (never do this)

x = 0   # The initial value of x, with global scope

def other_function():
    global x
    x = x + 5

def main_function():
    print(x)    # Just printing - no need to declare global yet
    global x   # So we can change the global x
    x = 10
    print(x)
    other_function()
    print(x)

Now you will get:

>>> 0    # Initial global value
>>> 10   # Now we've set it to 10 in `main_function()`
>>> 15   # Now we've added 5 in `other_function()`
zabop
  • 6,750
  • 3
  • 39
  • 84
Alex L
  • 8,748
  • 5
  • 49
  • 75
  • Wait, how did the other_function() in your first example get a value of 10? You did not assign a value to its parameter, so it will not be able to know that the value was 5. –  Dec 27 '12 at 09:21
  • 1
    @HwangYouJin The original value is `10`. You passing the variable x which has the value `10` to the `other_function`. It's like feeding into a machine. You give the machine a piece of bread (`x` in this case). You want to make toast. You give it a bread. Now the machine has the bread so it can use the bread. I think you should ask more questions to clear up confusions you have. – CppLearner Dec 27 '12 at 09:24
  • 2
    @HwangYouJin We set x to 10 with `x = 10`. We then ran `other_function(x)`, which means that we're passing the value of x (10) into `other_function`. In `other_function` the parameter is called `parameter`, rather than x, but it still has the value 10. Inside `other_function` we return `parameter + 5`, which is 10 + 5 = 15! – Alex L Dec 27 '12 at 09:27
  • @HwangYouJin Does this make more sense now? – Alex L Dec 27 '12 at 10:18
  • 1
    Ah...Ok... I already noticed you gave x its value before calling other_function()... sorry. Anyway, how do you turn a value returned from a function into a variable, or to say it otherwise, how do you give a variable a value which is the value returned by a function? –  Dec 27 '12 at 12:52
  • 1
    @HwangYouJin Just as easy as `variable = function(parameter)`. This will run the function, pass the parameter, and receive the returned value and put it into variable. If you were building a calculator you could do `result = add(5, 6)`, and `result` would now equal 11. (Assuming `add(x,y): return x+y`) – Alex L Dec 28 '12 at 02:13
  • Your point would perhaps be more clear if you made an assignment in `other_function(parameter)` so you wrote `parameter = 5` and returned that `return parameter`. Then in `main_function()` you should replace `x = other_function(x)` with `print other_function(x)`. The print out would be 10, 5, 10 – Norfeldt Jul 20 '13 at 09:43
  • @Matthew_Trevor's answer has a third option that is sometimes needed in more advanced scenarios. – Jonathan Sep 26 '17 at 07:40
15

Simply declare your variable outside any function:

globalValue = 1

def f(x):
    print(globalValue + x)

If you need to assign to the global from within the function, use the global statement:

def f(x):
    global globalValue
    print(globalValue + x)
    globalValue += 1
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • I have already used the global statement, but what I need is the current value of the global variable, which is in the function. –  Dec 27 '12 at 09:06
  • 3
    Your request doesn't seem to make sense. The current value of the global variable is in the global variable. Perhaps you could show your code to ease understanding. – Greg Hewgill Dec 27 '12 at 09:08
  • No, the function supposedly should change the variable and return its value and update the global variable, but I can't seem to do that –  Dec 27 '12 at 09:12
14

If you need access to the internal states of a function, you're possibly better off using a class. You can make a class instance behave like a function by making it a callable, which is done by defining __call__:

class StatefulFunction( object ):
    def __init__( self ):
        self.public_value = 'foo'

    def __call__( self ):
        return self.public_value


>> f = StatefulFunction()
>> f()
`foo`
>> f.public_value = 'bar'
>> f()
`bar`
Matthew Trevor
  • 14,354
  • 6
  • 37
  • 50
7

Using globals will also make your program a mess - I suggest you try very hard to avoid them. That said, "global" is a keyword in python, so you can designate a particular variable as a global, like so:

def foo():
    global bar
    bar = 32

I should mention that it is extremely rare for the 'global' keyword to be used, so I seriously suggest rethinking your design.

Arafangion
  • 11,517
  • 1
  • 40
  • 72
  • 1
    I just used a global variable because many of my functions share it and I don't want to assign lines of code to update every variable in each of the functions. –  Dec 27 '12 at 09:09
5

You could use module scope. Say you have a module called utils:

f_value = 'foo'

def f():
    return f_value

f_value is a module attribute that can be modified by any other module that imports it. As modules are singletons, any change to utils from one module will be accessible to all other modules that have it imported:

>> import utils
>> utils.f()
'foo'
>> utils.f_value = 'bar'
>> utils.f()
'bar'

Note that you can import the function by name:

>> import utils
>> from utils import f
>> utils.f_value = 'bar'
>> f()
'bar'

But not the attribute:

>> from utils import f, f_value
>> f_value = 'bar'
>> f()
'foo'

This is because you're labeling the object referenced by the module attribute as f_value in the local scope, but then rebinding it to the string bar, while the function f is still referring to the module attribute.

Matthew Trevor
  • 14,354
  • 6
  • 37
  • 50