0

Here is the complete code of my module, called util.py:

import my_other_module

__IMPORTANT_OBJECT__ = None

def getImportantObject():
    if __IMPORTANT_OBJECT__ is None:
        __IMPORTANT_OBJECT__ = my_other_module.ImportantObject()
    return __IMPORTANT_OBJECT__

My understanding is that variables prefixed with a double underscore are considered private to a module. The idea here is that I would like to store a private reference to the important object and the return it to anyone who asks for it via the getImportantObject() method. But I don't want the object to be initiated until the first time this method is called.

When I run my code, however, I get the following error:

File "/Users/Jon/dev/util.py", line 6, in getImportantObject
    if __IMPORTANT_OBJECT__ is None:
UnboundLocalError: local variable '__IMPORTANT_OBJECT__' referenced before assignment

What is the recommended way to accomplish what I am trying to do here?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
tadasajon
  • 14,276
  • 29
  • 92
  • 144

1 Answers1

5

The variable is not considered private; rather it's seen as a local variable.

Use the global keyword to mark it as such:

def getImportantObject():
    global __IMPORTANT_OBJECT__
    if __IMPORTANT_OBJECT__ is None:
        __IMPORTANT_OBJECT__ = my_other_module.ImportantObject()
    return __IMPORTANT_OBJECT__
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • I tried this and I got the same error. `UnboundLocalError: local variable '__IMPORTANT_OBJECT__' referenced before assignment` – tadasajon Dec 11 '12 at 17:28
  • 1
    @JonCrowell: Double check what you did. You probably mistyped the variable name. – Martijn Pieters Dec 11 '12 at 17:29
  • You're right, I did! But now I'm getting `NameError: global name '__IMPORTANT_OBJECT__' is not defined` – tadasajon Dec 11 '12 at 17:32
  • @JonCrowell: So now it is not matching the module-scope variable assignment (`__IMPORTANT_OBJECT__ = None`). The names have to match! – Martijn Pieters Dec 11 '12 at 17:35
  • I am looking at my code very closely. The variable name appears one time each in the first, second, third, and fourth lines of the functions. I have confirmed that they are identical in every case. (If I search and highlight, the variable names in all four lines match and get highlighted, so they must be identical) I have removed the trailing underscores (per your comment above). So I have `__IMPORTANT_OBJECT` in every line and the error points to the line `if __IMPORTANT_OBJECT is None:` and tells me `NameError: global name '__IMPORTANT_OBJECT' is not defined – tadasajon Dec 11 '12 at 17:42
  • 1
    @JonCrowell: Which means, that in the module scope, there is no variable named `__IMPORTANT_OBJECT`. I can't say anything else without seeing your code. – Martijn Pieters Dec 11 '12 at 17:45
  • Ahh, okay, I understand now. I had assumed that in your original answer you were telling me to move the variable declaration inside the function and that Python did something magic with the `global` keyword to make it a global variable even though it was defined in the function. But I guess what is going on is that I have to declare the variable outside the function and then tell my function that I want to refer to the global variable. – tadasajon Dec 11 '12 at 17:58
  • 1
    @Jon Crowell: When you changed the name from `__IMPORTANT_OBJECT__` to `__IMPORTANT_OBJECT` in some contexts the Python interpreter might change the name (mangle it) by adding another prefix because it thinks it's a private _class_ name. Try changing it to just have one leading underscore, i.e. `_IMPORTANT_OBJECT`. – martineau Dec 11 '12 at 19:45
  • 1
    @martineau: The problem has already been resolved; the `__IMPORTANT_OBJECT__ = None` line at module level was removed; a misunderstanding. – Martijn Pieters Dec 11 '12 at 19:46