在交互模式下运行时python有什么不同?

时间:2012-05-11 20:10:25

标签: python interactive interactive-mode

如果我使用Python的交互模式一次一个地输入命令,那么some Python code可以正常工作。如果保存为myscript.py并运行为'C:\Python27\python.exe myscript.py',则相同的代码会崩溃。

如果相同的代码在交互模式下工作,以什么方式运行Python代码作为脚本会导致崩溃?

This question询问如何判断python是否处于交互模式。但是,提问者只需要一个可靠的交互模式指纹。我想要一个交互模式不同的方式列表,特别注意这可能导致的问题。

例如:

  • sys.path可能不同
  • os.getcwd()可能不同
  • os.environ可能不同
  • this question
  • 的所有答案
  • This warning在多处理模块文档的开头

Python的交互式和脚本模式之间还有什么不同?

3 个答案:

答案 0 :(得分:3)

ThreadGreenlet在交互式环境中具有不同的行为。在某些情况下,主事件循环必须被黑客入侵。

Greenlet来自gevent模块,它是python中的并发任务。它有一个与Python(pthread)分开的内部上下文切换,并发工作非常好(根据我的经验)。 Greenlets的一些问题是,如果它们没有进行猴子修补(gevent中的模块),它们会阻止阻止C系统调用和套接字交互。

需要对主事件循环进行修补以使greenlet正常工作...如果在交互式环境中生成greenlet,它将不会切换上下文并执行,我忘了我的头脑怎么样了修补主事件循环(稍后将添加)。

失败的例子:

In [1]: from gevent.greenlet import Greenlet

In [2]: def print_hi():
   ...:     print 'hi'
   ...:     

In [3]: print_hi()
hi

In [4]: g = Greenlet(print_hi)

In [5]: g.start()

编辑:

在查看这个项目的一些代码后,我们如何破解ipython输入钩子以使用gevent

import sys
import select
import gevent

def stdin_ready():
    infds, outfds, erfds = select.select([sys.stdin], [], [], 0)
    if infds:
        return True
    else:
        return False

def inputhook_gevent():
    try:
        while not stdin_ready():
            gevent.sleep(0.001)
    except KeyboardInterrupt:
        pass

    return 0

# install the gevent inputhook
from IPython.lib.inputhook import inputhook_manager
inputhook_manager.set_inputhook(inputhook_gevent)
inputhook_manager._current_gui = 'gevent'

# First import the embeddable shell class
from IPython.frontend.terminal.embed import InteractiveShellEmbed

补丁示例:

In [6]: def say_hi():
   ...:     print "hi"
   ...:     

In [7]: g = gevent.greenlet.Greenlet(say_hi)

In [8]: g.start()

In [9]: hi  <-- Cursor is here so it printed hi

答案 1 :(得分:1)

看起来你正在与硬件交互,这带来了REPL和脚本之间最明显的区别:

脚本中的命令会立即立即运行,而REPL会等待人工输入。

也就是说,您可能遇到了一个时间问题,即执行上一个命令后硬件还没有为下一个命令做好准备。

答案 2 :(得分:0)

看看这一行

PCO_api = ctypes.oledll.LoadLibrary("SC2_Cam")

如果可以使用LoadLibrary的COMPLETE路径