奇怪的行为Django shell和iPython

时间:2015-06-18 20:59:55

标签: python django python-2.7 ipython django-shell

我在Django控制台中做了一些事情,我意识到全局变量在lambda表达式中无法识别,例如,如果你在python中执行以下代码,或者甚至在iPython控制台中它可以工作完美:

a = 10
foo = lambda x: x + a
foo(10) # returns 20

但是如果你使用iPython在Django shell中执行它,它就不起作用了:

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]: 
───────────

1 个答案:

答案 0 :(得分:3)

您可能遇到其他人遇到的错误:

https://github.com/ipython/ipython/issues/62#issuecomment-3854940

正如在线程中进一步说明的那样,在版本1.6之前,django使用IPython.embed()函数启动了ipython shell,这迫使ipython以单独的本地和全局命名空间开始。

django团队在此提交中修复了此问题: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