Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从IPython';什么是嵌入?_Python_Import_Closures_Ipython - Fatal编程技术网

如何从IPython';什么是嵌入?

如何从IPython';什么是嵌入?,python,import,closures,ipython,Python,Import,Closures,Ipython,我有时在脚本中的某个位置使用embed,以快速充实一些本地功能。最简单的例子: #!/usr/bin/env python # ... import IPython IPython.embed() 开发本地功能通常需要新的导入。但是,在函数中使用时,在IPython会话中导入模块似乎不起作用。例如: In [1]: import os In [2]: def local_func(): return os.path.sep In [3]: local_func() ----------

我有时在脚本中的某个位置使用
embed
,以快速充实一些本地功能。最简单的例子:

#!/usr/bin/env python

# ...

import IPython
IPython.embed()
开发本地功能通常需要新的导入。但是,在函数中使用时,在IPython会话中导入模块似乎不起作用。例如:

In [1]: import os

In [2]: def local_func(): return os.path.sep

In [3]: local_func()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-3-f0e5d4635432> in <module>()
----> 1 local_func()

<ipython-input-2-c530ce486a2b> in local_func()
----> 1 def local_func(): return os.path.sep

NameError: global name 'os' is not defined
模块名称可能是“关闭”最常见的东西

这个问题有什么解决办法吗

更新:这个问题不仅适用于闭包,而且也适用于


免责声明:我会自己发布一个(不满意的)问题答案——不过还是希望有更好的解决方案。

Update:同样只是一个解决办法,但稍微简单一些:
globals().Update(locals())


我没有一个通用的解决方案,但至少有一个解决方法:定义本地函数后,可以将会话的
locals()
添加到刚刚定义的函数的
func\u globals
,例如:

In [1]: import os

In [2]: def local_func(): return os.path.sep

In [3]: local_func.func_globals.update(locals())

In [4]: local_func()
Out[4]: '/'
但是,应注意,这只是“手动关闭”,在以下情况下不会作为常规关闭:

In [1]: x = 1

In [2]: def local_func(): return x

In [3]: local_func.func_globals.update(locals())

In [4]: local_func()
Out[4]: 1

In [5]: x = 42

In [6]: local_func() # true closure would return 42
Out[6]: 1

In [7]: local_func.func_globals.update(locals()) # but need to update again

In [8]: local_func()
Out[8]: 42

至少它可以解决臭名昭著的
全局名称“…”没有定义的导入问题。

我也有同样的问题。我使用这个技巧来处理在函数外部调用
embed()
的情况,因此
globals()
locals()
应该是同一个字典

最简单的方法是在ipython启动后调用以下函数

ipy = get_ipython()
setattr(ipy.__class__, 'user_global_ns', property(lambda self: self.user_ns))
另一种方法是子类化InteractiveShellEmbed

class InteractiveShellEmbedEnhanced(InteractiveShellEmbed):
    @property
    def user_global_ns(self):
        if getattr(self, 'embedded_outside_func', False):
            return self.user_ns
        else:
            return self.user_module.__dict__

    def init_frame(self, frame):
        if frame.f_code.co_name == '<module>':
            self.embedded_outside_func = True
        else:
            self.embedded_outside_func = False

(默认行为是由于
a
time
未添加到
globals()
ipython
不会对局部函数(上面定义的lambda)进行闭包,并坚持在全局范围内查找变量。搜索
closure

截至2017年2月,我仍然注意到sys.version的问题是
2.7.12(默认值,2016年11月19日06:48:10)[GCC 5.4.0 20160609]
。非常有趣。你认为把这些贡献给iPython有意义吗?也许这可以解决问题,@bluenote10我不是python或IPython方面的专家。我不确定在函数外部启动时,该代码是否在所有情况下都能工作。我只能分享我的代码,让专家告诉我它是作为解决方案还是指向解决问题的方向。我已经将一个更完整的代码片段放到了您的中,它还提供了从函数嵌入IPython时的帮助。
class InteractiveShellEmbedEnhanced(InteractiveShellEmbed):
    @property
    def user_global_ns(self):
        if getattr(self, 'embedded_outside_func', False):
            return self.user_ns
        else:
            return self.user_module.__dict__

    def init_frame(self, frame):
        if frame.f_code.co_name == '<module>':
            self.embedded_outside_func = True
        else:
            self.embedded_outside_func = False
a=3
(lambda :a)()    # default behavior: name 'a' is not defined
import time
(lambda: time.time())()  # default behavior: name 'time' is not defined