奇怪的行为 Django shell 和 iPython
Strange behaviour Django shell and iPython
我在 Django 控制台中做了一些事情,我意识到在 lambda
表达式中无法识别全局变量,例如,如果您在 python 中执行以下代码,甚至在 iPython 控制台中它完美运行:
a = 10
foo = lambda x: x + a
foo(10) # returns 20
但是如果你在 Django shell 中使用 iPython 执行它,它就不起作用:
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
iPython版本0.13.2
提前致谢!
编辑
事件如果我在 lambda 函数之前分配 a
问题仍然存在:
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]:
───────────
您可能遇到了其他人在这里遇到的错误:
https://github.com/ipython/ipython/issues/62#issuecomment-3854940
正如线程中进一步解释的那样,在版本 1.6 之前,django 使用 IPython.embed()
函数启动 ipython shell,这会强制 ipython 从单独的本地和全局命名空间开始。
django 团队在此提交中修复了 1.6 中的这个问题:https://github.com/django/django/commit/3570ff734e93f493e023b912c9a97101f605f7f5
这是旧版本 Django(在本例中为 1.4.14)的反向移植修复:https://github.com/theatlantic/django/commit/9dfe12c40af23956dc12e3427e3e7e63ebc360c9
如果您在另一个函数内手动调用 IPython.embed()
(创建闭包),则可以重现此问题,即使您使用常规 python/ipython shell。使用 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
我在 Django 控制台中做了一些事情,我意识到在 lambda
表达式中无法识别全局变量,例如,如果您在 python 中执行以下代码,甚至在 iPython 控制台中它完美运行:
a = 10
foo = lambda x: x + a
foo(10) # returns 20
但是如果你在 Django shell 中使用 iPython 执行它,它就不起作用:
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
iPython版本0.13.2
提前致谢!
编辑
事件如果我在 lambda 函数之前分配 a
问题仍然存在:
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]:
───────────
您可能遇到了其他人在这里遇到的错误:
https://github.com/ipython/ipython/issues/62#issuecomment-3854940
正如线程中进一步解释的那样,在版本 1.6 之前,django 使用 IPython.embed()
函数启动 ipython shell,这会强制 ipython 从单独的本地和全局命名空间开始。
django 团队在此提交中修复了 1.6 中的这个问题:https://github.com/django/django/commit/3570ff734e93f493e023b912c9a97101f605f7f5
这是旧版本 Django(在本例中为 1.4.14)的反向移植修复:https://github.com/theatlantic/django/commit/9dfe12c40af23956dc12e3427e3e7e63ebc360c9
如果您在另一个函数内手动调用 IPython.embed()
(创建闭包),则可以重现此问题,即使您使用常规 python/ipython shell。使用 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