1

Code is as follows:

def create_dict():
  my_dict = {}
  return my_dict

create_dict()
print (my_dict)

To which I get:

NameError: name 'my_dict' is not defined

If I assign the returned dictionary like this:

my_dict = create_dict()

instead of the create_dict() line then it works but this script will be called multiple times so I don't want my_dict being overwritten each time I call it. What I want to be able to do is call the function creat_dict() once at the beginning to create the dictionary then just add/remove things as I see fit. If I keep calling the script then my_dict will always be overwritten with an empty dictionary.

I could do this:

if my_dict exists: #This bit is pseudo code
  my_dict = {}
else:
  pass

but I'm curious nonetheless whether it is possible to return a 'Global' dictionary from a function (that terminology may be off).

BloodSexMagik
  • 398
  • 1
  • 3
  • 14
  • `my_variable_on_the_outside = create_dict()`. You'll have to find another way to persist the data so that it is not "an empty dictionary" each time a *new process* is run. – user2864740 May 03 '16 at 16:44
  • 2
    Possible duplicate of [Using global variables in a function other than the one that created them](http://stackoverflow.com/questions/423379/using-global-variables-in-a-function-other-than-the-one-that-created-them) – Frank Bryce May 03 '16 at 16:46
  • What do you mean by "but this script will be called multiple times so I don't want my_dict being overwritten each time I call it"? if you need to create the dict once at the beginning, you should call that function just one time. – eguaio May 03 '16 at 16:46

3 Answers3

4

Just put global in front of the variable, and conditionally instantiate it.

def create_dict():
  global my_dict
  if 'my_dict' not in globals():
    my_dict = {}

create_dict()
print (my_dict)
Frank Bryce
  • 8,076
  • 4
  • 38
  • 56
  • This was exactly what I was looking for, thank you. As alluded to in answers below is there any reason NOT to use globals? – BloodSexMagik May 03 '16 at 17:20
  • There are some cases where you need to use globals, but they are rare. IMHO, in this case is probably a poor design what is making you wanting to use them. If you show how you are structuring your code, I'm sure there is a cleaner way to satisfy your requirements. The use of global variables is known to be bad because it reduces modularity and by this reason it can introduce serious, hard to track, bugs in your code. Specially if these variables are not read-only. – eguaio May 03 '16 at 17:26
1

I don't think in this case it is good to suggest the use of global variables.

What you need to do is to put the my_dict = create_dict() line outside that script you keep calling, and put it just once, at the beginning, in whatever is the other place from where you keep calling your script.

eguaio
  • 3,754
  • 1
  • 24
  • 38
0

Well, you can implement this behavior with the global statement for example:

def create_dict():
  global my_dict
  my_dict = {}

To check if my_dict exists in the global scope and to avoid re-assignment inside the function's body you have to do something like the following:

def create_dict():
  if not "my_dict" in globals(): 
        global my_dict
        my_dict = {}

Here's a little note you have to take into your consideration, it's best to keep the function self-contained. In other words, global variables assigned inside the function may make your program maintenance a bit harder. I wouldn't be harsh here and say avoid them at all costs, but I'd rather say, use them when and only when you think they're truly necessary. The Zen of Python says: "Simple is better than complex."

GIZ
  • 4,409
  • 1
  • 24
  • 43
  • You should use `my_dict not in globals()` instead of `not my_dict in globals()`. See [PEP 0008](https://www.python.org/dev/peps/pep-0008/) – CodenameLambda May 03 '16 at 16:59
  • @CodingLambdas My original code works, however, I wrote `my_dict` instead of `"my_dict"` in the header of the `if` statement, because here we check the keys of the dictionary and they're strings in fact. And thank you for noting this. – GIZ May 03 '16 at 17:19