Global name 'x' is not defined. But it is!!!

Posted on
Thu Oct 06, 2011 11:16 am
macpro offline
User avatar
Posts: 765
Joined: Dec 29, 2005
Location: Third byte on the right

Global name 'x' is not defined. But it is!!!

I'm having troubles with global variables in Python scripts.

Here's an example (found it here):

Code: Select all
x = 0

def change():
   """changing x: need global"""
    global x
    print 'adding 1'
    x += 1

def show():
    """not changing x: no global needed, if global x exist in context"""
    print 'show:', x

print x
show()
change()
show()
print x

When you put this in a file called "global.py" and run it in the terminal, it will give this output:

Code: Select all
$ python global.py
0
show: 0
adding 1
show: 1
1


But when I create an Action Group that fires this python script, I get this error in the Event Log window:

Code: Select all
  Action Group                    Global Test
  Script Error                    global.py: global name 'x' is not defined
  Script Error                    Exception Traceback (most recent call shown last):

     global.py, line 14, at top level
     global.py, line 11, in show
NameError: global name 'x' is not defined


Is this a bug or a feature?

Posted on
Thu Oct 06, 2011 12:15 pm
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: Global name 'x' is not defined. But it is!!!

Under-the-hood the python script source executed by Indigo gets wrapped into a function. So the 'x =' definition at the top isn't really creating a global. It is creating a local variable at the hidden wrapper function level. The functions in your script (which are nested inside the function Indigo automatically uses as a wrapper) get read-only access to the variable x. There is no way to get write access since the "global" declaration only works for true global variables.

We are investigating how we might be able to fix this on our end automatically, but I'm not sure it will be possible without unreasonable effort. But I have a couple of workarounds. The first is to not use global variables and pass the variable as a parameter in the methods. :-) But if you need global variable behavior, then you can force the initial declaration of x to really be a global by changing the first line to:

Code: Select all
globals()["x"] = 0

The rest of the script should then work as expected.

Image

Posted on
Thu Oct 06, 2011 12:44 pm
jay (support) offline
Site Admin
User avatar
Posts: 18200
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Global name 'x' is not defined. But it is!!!

During my CS undergrad, I was taught that global variables == EVIL.

Others may have different experiences, but I'd highly recommend avoiding them.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Thu Oct 06, 2011 1:30 pm
macpro offline
User avatar
Posts: 765
Joined: Dec 29, 2005
Location: Third byte on the right

Re: Global name 'x' is not defined. But it is!!!

Making x a global works.
Tried it into my real Python code and there it works as well.
So for me it's a good work around.

Thanks.

Posted on
Tue Oct 25, 2011 7:51 pm
Perry The Cynic offline
Posts: 836
Joined: Apr 07, 2008

Re: Global name 'x' is not defined. But it is!!!

Another work-around for Python's global-phobia is to use structures or objects:

Code: Select all
globs = { 'x': 0 }
... somewhere deep down in a function ...
       globs['x'] += 1

No need to mess with "true" globals, since globs is never assigned-to at all. (You're just changing its innards.)

Cheers
-- perry

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 3 guests