waka-waka-waka
waka-waka-waka

Reputation: 1045

python variable change scope

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!

Upvotes: 0

Views: 1078

Answers (2)

user1019517
user1019517

Reputation:

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.

Upvotes: 1

msvalkon
msvalkon

Reputation: 12077

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.

Upvotes: 3

Related Questions