【问题标题】:Strange behaviour Django shell and iPython奇怪的行为 Django shell 和 iPython
【发布时间】:2015-09-04 16:52:29
【问题描述】:

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

【问题讨论】:

  • 如果你访问a会发生什么?
  • @PadraicCunningham 它没有发生任何事情,问题停留在 lambda 表达式中
  • 尝试在 lambda 函数之前分配 a = 10
  • @Pynchia 请看我的编辑:D
  • 您使用的是什么版本的 django?您如何使用python manage.py shell -i ipython 启动 ipython shell?您的代码适用于我在 django 1.8.2 上使用 ipython shell

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


【解决方案1】:

您可能遇到了其他人在这里遇到的错误:

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

【讨论】:

    猜你喜欢
    • 2015-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 2016-02-22
    • 2017-01-30
    • 2014-09-27
    • 1970-01-01
    相关资源
    最近更新 更多