1

Here is my code :

a module settings.py:

My_KEY = ""

and I am using this MY_KEY in another module

my_module.py

from settings import My_KEY


def function_a():
    MY_KEY = "abcd"


def function_b():
    function_a();
    print My_KEY

I expect to see a "abcd" in output when I call function_b(), but how come I get empty string. I am totally lost

1
  • If you want to explicitly change the module level variable it's clearer and more explicit to do it directly: import settings and then settings.MY_KEY = 'abcd' makes it clear that you wanted to change the variable. BTW it's a convention to use ALL_CAPS for constants that don't change, so it's doubly confusing here Commented Aug 20, 2013 at 23:30

3 Answers 3

6

By default, when an assignment statement is encountered inside a function, Python takes the variable on the left-hand side to be a local variable.

If you want to modify a global variable from within a function, use the global statement to declare the variable to be a global:

def function_a():
    global My_KEY
    My_KEY = "abcd"

However, it is better to avoid modifying globals from within functions. In the long run it makes code harder to understand. You could instead pass My_KEY as a return value from function_a:

def function_a():
    My_KEY = "abcd"
    return My_KEY

def function_b():
    My_KEY = function_a()
    print My_KEY
Sign up to request clarification or add additional context in comments.

Comments

3

It's all about python scoping and namespacing.

You have actually 3 versions of My_KEY:

  • global variable My_KEY imported
  • My_KEY in function_a (I think you have a typo there: should be My_KEY instead of MY_KEY)
  • My_KEY in function_b

You can mark variable inside a function as global in order to modify it:

def function_a():
    global My_KEY
    My_KEY = "abcd"

Comments

0

Scoping is part of the issue but you also need to be careful about how you import variables. from settings import My_KEY creates a new variable in the local module's namespace that points to the original string. When you assign a different string to your module's My_KEY, that doesn't affect the My_KEY in the settings module. Its not a problem when you are modifying mutable objects, but any time you reassign a value, You are better off just importing the module the module itself and using the variable's dotted name.

settings.py:

My_KEY = ""

then a quick test in the shell

>>> from settings import My_KEY
>>> def function_a():
...     global My_KEY
...     My_KEY="abcd"
... 
>>> My_KEY
''
>>> function_a()
>>> My_KEY
'abcd'
>>> 
>>> # here's where it gets funky... the original settings.My_KEY didn't change 
>>> 
>>> import settings
>>> settings.My_KEY
''
>>> 

Comments

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.