Reputation: 10811
I was doing some stuff in the Django console and I realized that the global variables are not recognized inside the lambda
expression, for example if you execute the following code inside a python or even inside an iPython console it works perfectly:
a = 10
foo = lambda x: x + a
foo(10) # returns 20
But if you execute it inside the Django shell with iPython it doesn't work:
In [8]: foo = lambda x: x + a
In [9]: a = 10
In [10]: foo(10)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 foo(10)
/usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in <lambda>(x)
----> 1 foo = lambda x: x + a
NameError: global name 'a' is not defined
The iPython version 0.13.2
Thank you in advance!
EDIT
Event if I assign a
before the lambda funciton the problem stills:
In [1]: a = 10
In [2]: foo = lambda x: x + a
In [3]: foo(10)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 foo(10)
/usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in <lambda>(x)
----> 1 foo = lambda x: x + a
NameError: global name 'a' is not defined
In [4]:
───────────
Upvotes: 0
Views: 225
Reputation: 2477
You might be experiencing the bug others have encountered here:
https://github.com/ipython/ipython/issues/62#issuecomment-3854940
As explained in the thread a little further down, prior to version 1.6, django was starting the ipython shell using the IPython.embed()
function, which was forcing ipython to start with separate local and global namespaces.
The django team fixed this issue in 1.6 in this commit: https://github.com/django/django/commit/3570ff734e93f493e023b912c9a97101f605f7f5
Here is a backport fix for older versions of Django (1.4.14 in this case): https://github.com/theatlantic/django/commit/9dfe12c40af23956dc12e3427e3e7e63ebc360c9
You can reproduce this issue if you manually call IPython.embed()
inside of another function (creating a closure), even if you use a regular python/ipython shell. Tested with ipython 3.1.0:
>>> from IPython import embed
>>> def test():
... embed()
...
>>> test()
Python 2.7.9 (default, Feb 10 2015, 03:28:08)
Type "copyright", "credits" or "license" for more information.
IPython 3.1.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: a = 10
In [2]: foo = lambda x: x+a
In [3]: foo(10)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-3-08cbc4a9df91> in <module>()
----> 1 foo(10)
<ipython-input-2-3ecd5afea150> in <lambda>(x)
----> 1 foo = lambda x: x+a
NameError: global name 'a' is not defined
Upvotes: 3