0

I have a simple use case. I need to access variables that are outside the scope of a function. My problem is that, I am unable to see the changes being reflected.

I have:

def somefunc():
    print a # None
    print b # None

def main():
    a = 'whatever'
    b = 10
    module = modules[__name__]
    getattr(module, 'somefunc')

if __name__ == 'main':
    # NOTE: if and b are changed here, then somefunc can see those changes
    a = None
    b = None
    main()

NOTE: I cannot pass arguments to somefunc because of some other limitation. How do I see the changes to a and b in somefunc?

Thanks!

4
  • 1
    I didnt give you -1, but this is poor program design ... you really should be using data encapsulation and passing it around ... global variables are just asking for trouble Commented Apr 2, 2014 at 19:18
  • I totally understand. This should be in a class by itself. I declared something global probably after a couple of years, but sometimes shit needs to get done, whether or not it is architecturally right. #startupproblems Commented Apr 2, 2014 at 19:20
  • 1
    it will hurt alot more to fix later than just fixing it now with a better design ... Commented Apr 2, 2014 at 19:21
  • You use two terms erroneously: "variable", because this word is ambiguous in Python, and "scope", because all the people make a mistake concerning the sense of this word. But it's a too complex subject that doesn't interest people, and I have no time and energy to explain. Commented Apr 2, 2014 at 21:10

2 Answers 2

3

You need to declare them global using the global keyword. The global keyword allows you to change the value of a variable that is defined inside the module, outside of any function or class.

You can always print global variables without declaring them, and you can modify global mutable containres like lists and dicts without declaring them global, but you cannot assign values. Heres the official documentation, below is a working example.

a = None
b = None

def somefunc():
    # This works.
    print a # None
    print b # None

def main():
    global a, b
    a = 'whatever'
    b = 10
    # somefunc() exist in the local scope, you don't need the getattr.
    # just call it.
    somefunc()

if __name__ == '__main__': # You were missing the undescores surrounding main
    main()

Demo output:

msvalkon@Lunkwill:/tmp$ python t.py
whatever
10

It's a little bad practice to use globals. They have their use cases but usually there is a better way, like passing the data as arguments to functions or wrapping all functions inside a class which holds the value you'd normally make global. Globals are great for storing static information, like configuration info, a server address that doesn't change, a port number and so forth. You should try to avoid using them like normal variables.

Sign up to request clarification or add additional context in comments.

4 Comments

winner winner chicken dinner
is it a bad approach using global?
yes ... but if thats the only way you can do it as you claim then thats the only way to do it
I think most people will tell you that globals are pretty much a bad idea. You could always be passing by reference instead, or create a class, or any number of things other than globals.
1

You need to use the global keyword to prevent the scope of your function from overwriting the scope of a = None and b = None

def somefunc():
    print a # None
    print b # None

def main():
    global a, b
    a = 'whatever'
    b = 10
    module = modules[__name__]
    getattr(module, 'somefunc')

if __name__ == '__main__': # you need underscores around __main__ 
    a = None
    b = None
    main()

bam.

2 Comments

although you do not need that when only referencing them (only when setting them)
guess I'm just a natural with extensibility, you know... nbd

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.