请考虑以下代码段:
a = ''
def assign(letter):
global a
a = letter
如果我在IDLE中加载它并运行它(Python 2.7.6),它的行为符合预期:
>>> a
''
>>> assign('b')
>>> a
'b'
但是在Canopy Editor(1.3.1)中内置的IPython中,全局变量不会被函数更改:
In [2]: a
Out[2]: ''
In[3]: assign('b')
In[4]: a
Out[4]: ''
这是预期的行为吗?如何在IPython中操纵全局变量?
为了记录,我意识到全局变量的危险。我在尝试重现类中讨论的缓存例程时遇到了这个问题:https://www.youtube.com/watch?v=OgPS2ziCEaw
答案 0 :(得分:1)
1)IDLE没有使用IPython,所以比较就不重要了。
2)Canopy中的run
命令放置一个标准的ipython %run
magic命令,你可以在Canopy的ipython命令行上看到它,然后执行它。
3)你报告的是ipython run magic命令的正常行为。第一次遇到时有点违反直觉;简短的解释是,正在运行的模块的全局命名空间与ipython解释器的全局命名空间不同。运行模块后,其命名空间将被复制到解释器的命名空间中(这就是解释器中定义a
的原因),但执行函数assign
(在模块中定义)并且其全局命令因此引用模块全局命名空间),改变模块命名空间中的a
,而不是解释器命名空间中的副本。
4)这可能看起来像是不必要的混乱行为,但目的是确保从ipython提示符运行的模块运行" clean"解释器命名空间中可能存在的任何flotsam。
5)如果您不想要这种行为,请使用%run -i mymodule.py
,这会导致模块直接在解释器的全局命名空间中运行。如果这样做,您的示例与空闲相同。在Canopy中,最简单的方法是按下python shell中的向上箭头以调用%run
命令,然后编辑它以插入-i
。
6)上面的评论员Padraic说他不能在ipython中复制它。我能看到的唯一解释是他将IPython配置为在-i
模式下默认运行,或者他实际上并没有运行OP的代码片段,而是直接在其中执行这些命令。解释器,因此只使用解释器命名空间。