我想从 python 调用外部进程。我正在调用的进程读取输入字符串并给出标记化结果,然后等待另一个输入(如果有帮助,二进制是 MeCab 标记器)。
我需要通过调用此过程来标记数千行字符串。
问题是 Popen.communicate()工作但在给出 STDOUT 结果之前等待进程结束。我不想继续关闭和打开新的子流程数千次。 (而且我不想发送整个文本,将来很容易超过数万行。)
from subprocess import PIPE, Popen
with Popen("mecab -O wakati".split(), stdin=PIPE,
stdout=PIPE, stderr=PIPE, close_fds=False,
universal_newlines=True, bufsize=1) as proc:
output, errors = proc.communicate("foobarbaz")
print(output)
我试过阅读 proc.stdout.read()而不是使用 communicate 但它被 stdin 阻止并且在 proc.stdin.close() 之前不返回任何结果叫做。这又意味着我每次都需要创建一个新流程。
我已经尝试通过类似的问题实现队列和线程,如下所示,但它要么不返回任何东西,因此它停留在 While True 上,或者当我强制 stdin 缓冲区填充时重复发送字符串,一次输出所有结果。
from subprocess import PIPE, Popen
from threading import Thread
from queue import Queue, Empty
def enqueue_output(out, queue):
for line in iter(out.readline, b''):
queue.put(line)
out.close()
p = Popen('mecab -O wakati'.split(), stdout=PIPE, stdin=PIPE,
universal_newlines=True, bufsize=1, close_fds=False)
q = Queue()
t = Thread(target=enqueue_output, args=(p.stdout, q))
t.daemon = True
t.start()
p.stdin.write("foobarbaz")
while True:
try:
line = q.get_nowait()
except Empty:
pass
else:
print(line)
break
也查看了 Pexpect 路由,但它的 windows 端口不支持一些重要的模块(基于 pty 的模块),所以我也无法应用它。
我知道有很多类似的答案,而且我已经尝试了其中的大部分。但我尝试过的任何东西似乎都无法在 Windows 上运行。
编辑:关于我正在使用的二进制文件的一些信息,当我通过命令行使用它时。它运行并标记我给出的句子,直到我完成并强行关闭程序。
(...waits_for_input -> input_recieved -> output -> waits_for_input...)
谢谢。
最佳答案
如果 mecab 使用带有默认缓冲的 C FILE 流,则管道标准输出有一个 4 KiB 缓冲区。这里的想法是,程序可以有效地使用小的、任意大小的读取和写入缓冲区,并且底层标准 I/O 实现处理自动填充和刷新更大的缓冲区。这最大限度地减少了所需的系统调用次数并最大限度地提高了吞吐量。显然,您不希望交互式控制台或终端 I/O 或写入 stderr 时出现这种行为。在这些情况下,C 运行时使用行缓冲或不使用缓冲。
程序可以覆盖此行为,并且某些程序确实具有设置缓冲区大小的命令行选项。例如,Python 具有“-u”(无缓冲)选项和 PYTHONUNBUFFERED 环境变量。如果 mecab 没有类似的选项,则 Windows 上没有通用的解决方法。 C运行时的情况太复杂了。 Windows 进程可以静态或动态链接到一个或多个 CRT。 Linux 上的情况不同,因为 Linux 进程通常将单个系统 CRT(例如 GNU libc.so.6)加载到全局符号表中,这允许 LD_PRELOAD 库配置 C FILE 流。 Linux stdbuf 使用这个技巧,例如stdbuf -o0 mecab -O wakati。
一个试验选项是调用 CreateConsoleScreenBuffer 并从 msvcrt.open_osfhandle 获取句柄的文件描述符。然后将其作为 stdout 传递,而不是使用管道。子进程会将其视为 TTY 并使用行缓冲而不是全缓冲。然而,管理这一点并非易事。这将涉及读取(即 ReadConsoleOutputCharacter)由另一个进程主动写入的滑动缓冲区(调用 GetConsoleScreenBufferInfo 以跟踪光标位置)。这种互动不是我曾经需要甚至尝试过的。但是我非交互地使用了控制台屏幕缓冲区,即在 child 退出后读取缓冲区。这允许从直接写入控制台而不是 stdout 的程序读取多达 9,999 行输出,例如调用 WriteConsole 或打开“CON”或“CONOUT$”的程序。
关于python - 子进程,从 STDOUT 读取时重复写入 STDIN (Windows),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42991214/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD