简体   繁体   English

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

[英]In what ways is python different when run in interactive mode?

I have some Python code that works as expected if I type the commands one-at-a-time using Python's interactive mode. 如果我使用Python的交互模式一次一个地键入命令,我有一些Python代码可以正常工作。 The same code crashes if saved as myscript.py and run as 'C:\\Python27\\python.exe myscript.py' . 如果保存为myscript.py并运行为'C:\\Python27\\python.exe myscript.py'则相同的代码崩溃。

In what ways could running Python code as a script cause it to crash, if the same code works in interactive mode? 如果相同的代码在交互模式下工作,以何种方式运行Python代码作为脚本会导致它崩溃?

This question asks for ways to tell if python is in interactive mode. 这个问题询问了如何判断python是否处于交互模式。 However, the asker just wants a single, reliable fingerprint of interactive mode. 但是,提问者只需要一个可靠的交互模式指纹。 I'd like a list of ways that interactive mode is different, with particular attention to problems this can cause. 我想要一个交互模式不同的方式列表,特别注意这可能导致的问题。

For example: 例如:

  • sys.path could be different sys.path可能不同
  • os.getcwd() could be different os.getcwd()可能不同
  • os.environ could be different os.environ可能会有所不同
  • All the answers to this question 这个问题的所有答案
  • This warning at the beginning of the multiprocessing module documentation 多处理模块文档开头的此警告

What else could be different between Python's interactive and script mode? Python的交互模式和脚本模式之间还有什么不同?

Thread s and Greenlet s have different behavior in an interactive environment. ThreadGreenlet在交互式环境中具有不同的行为。 The main event loop has to be hacked in some instances. 在某些情况下,主事件循环必须被黑客入侵。

Greenlet is from the gevent module which is a concurrent task in python. Greenlet来自gevent模块,它是python中的并发任务。 It has an internal context switching separate from Python's (pthread) and the concurrency works really well (in my experience). 它有一个与Python(pthread)分开的内部上下文切换,并发工作非常好(根据我的经验)。 Some of the issues with Greenlets is that they block on blocking C-system calls and socket interactions if they're not monkey-patched (module in gevent ). Greenlets的一些问题是,如果它们没有进行猴子修补( gevent模块),它们会阻止阻塞C系统调用和套接字交互。

The main event-loop needs to be patched in order for the greenlets to work correctly... If you spawn a greenlet in an interactive environment it will not switch contexts and execute, I forgot how off the top of my head how to patch the main event loop (will add later). 主要的事件循环需要打补丁才能使greenlet正常工作......如果你在交互式环境中生成greenlet它不会切换上下文并执行,我忘记了如何修补我的头脑主事件循环(稍后将添加)。

Example of failure: 失败的例子:

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()

Edit: 编辑:

After looking at some of the code on this project here's how we hacked the ipython input hook to use gevent 在查看了这个项目的一些代码之后,我们如何破解了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

Patched Example: 修补示例:

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

It looks like you're interacting with hardware, which brings up the most glaring difference between the REPL and a script: 看起来你正在与硬件交互,这带来了REPL和脚本之间最明显的区别:

Commands in a script run immediately as soon as possible, whereas the REPL waits for human input. 脚本中的命令会立即立即运行,而REPL则等待人工输入。

That is to say, you are probably having a timing issue where the hardware isn't ready for the next command so soon after executing the previous. 也就是说,您可能遇到了一个时序问题,即执行前一个命令后硬件还没有为下一个命令做好准备。

Take a look at this line 看看这一行

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

If you can use the COMPLETE path for LoadLibrary 如果可以使用LoadLibrary的COMPLETE路径

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM