0

首先我应该注意到:我是一个不了解 ruby​​ 的 Python 程序员!

现在,我需要输入一个 ruby​​ 程序的标准输入,并用一个 python 程序捕获脚本的标准输出。
我尝试了这个(第四个解决方案),代码在 python2.7 中有效,但在 python3 中无效;python3 代码读取没有输出的输入。

现在,我需要一种将 ruby​​ 程序绑定到 python 2 或 3 的方法。

我的尝试:

这段代码用六个模块编写,具有跨版本兼容性。

  • 蟒蛇代码:

    from subprocess import Popen, PIPE as pipe, STDOUT as out
    
    import six
    
    print('launching slave')
    slave = Popen(['ruby', 'slave.rb'], stdin=pipe, stdout=pipe, stderr=out)
    
    while True:
        if six.PY3:
            from sys import stderr
            line = input('enter command: ') + '\n'
            line = line.encode('ascii')
        else:
            line = raw_input('entercommand: ') + '\n'
        slave.stdin.write(line)
        res = []
        while True:
            if slave.poll() is not None:
                print('slave rerminated')
                exit()
            line = slave.stdout.readline().decode().rstrip()
            print('line:', line)
            if line == '[exit]': break
            res.append(line)
        print('results:')
        print('\n'.join(res))
    
  • 红宝石代码:

    while cmd = STDIN.gets
        cmd.chop!
        if cmd == "exit"
            break
        else
            print eval(cmd), "\n"
            print "[exit]\n"
            STDOUT.flush
        end
    end
    

笔记:

欢迎使用另一种方法来做这件事!(如套接字编程等)
另外我认为不使用管道作为标准输出并使用类似文件的对象是一个更好的主意。(如tempfileStringIO或等)

4

2 回答 2

1

这是因为bufsize。在 Python 2.x 中,默认值为 0(无缓冲)。在 Python 3.x 中,它改为-1(使用系统的默认缓冲区大小)。

明确指定它将解决您的问题。

slave = Popen(['ruby', 'slave.rb'], stdin=pipe, stdout=pipe, stderr=out, bufsize=0)

演示

于 2014-09-27T06:38:32.980 回答
0

下面是我如何使用 Ruby 和 Python3 的代码。

红宝石奴隶

# read command from standard input:
while cmd = STDIN.gets
  # remove whitespaces:
  cmd.chop!
  # if command is "exit", terminate:
  if cmd == "exit"
    break
  else
    # else evaluate command, send result to standard output:
    print eval(cmd), "\n"
    print "[exit]\n"
    # flush stdout to avoid buffering issues:
    STDOUT.flush
  end
end

蟒蛇大师

from subprocess import Popen, PIPE as pipe, STDOUT as out

print('Launching slave')
slave = Popen(['ruby', 'slave.rb'], stdin=pipe, stdout=pipe, stderr=out, bufsize=0)

while True:
    from sys import stderr
    line = input('Enter command: ') + '\n'
    line = line.encode('ascii')
    slave.stdin.write(line)
    res = []
    while True:
        if slave.poll() is not None:
            print('Slave terminated')
            exit()
        line = slave.stdout.readline().decode().rstrip()
        if line == '[exit]': break
        res.append(line)
    print('results:')
    print('\n'.join(res))

于 2021-07-09T11:04:23.777 回答