基于事件的流程输出排出
drainers的Python项目详细描述
drainers是一个围绕子流程的抽象。popen来读取和控制 处理输出事件。它还允许您中止正在运行的进程 优雅地或有力地而不必直接与 自行处理或线程。
概述
定义流程
drainer是一个工厂和控制器包装器 subprocess.popen并因此接受所有(可选)参数 子流程popen的初始值设定项。例如,最小的 drainer接受命令数组:
from drainers import Drainer def ignore_event(line, is_err): pass my_drainer = Drainer(['ls', '-la'], read_event_cb=ignore_event) my_drainer.start()
但是,也允许额外的参数:
my_drainer = Drainer(['echo', '$JAVA_HOME'], shell=True, bufsize=64, read_event_cb=ignore_event) my_drainer.start()
保留的drainer的两个参数是 stdout和stderr。排水器要求 subprocess.pipe显式地,并相应地为您设置它们。
定义回调
drainer的优势在于 进程的标准输出或标准错误流导致回调 正在调用的函数。这允许您处理几乎所有的进程' 输出,只要是基于行的。
回调函数可以使用 构造函数,如上面的示例所示。这是强制性的。回拨 指定的函数需要有特定的签名:
def my_callback(line, is_err): ...
它应该有两个参数:line(字符串)和is_err(布尔值)。 后者表示从标准错误流读取行。 没有别的了。它不需要返回任何东西:它是返回 值将被忽略。回调也可以是类方法,如 下面的例子。注意,在这些情况下,您将把foo.my_方法作为 参数的值:
class MyClass(object): def my_method(self, line, is_err): ... foo = MyClass() my_drainer = Drainer(['ls'], read_event_cb=foo.my_method) my_drainer.start()
当前的粒度是一行。如果要读取预定义的 数据块(行),改用buffereddrainer。见 例如examples/buffer_results.py。
中止进程
drainer允许您在执行过程中中止正在运行的进程, 强制发送进程aterminate()消息(python等价于 unixsigterm消息)当某个条件出现时。默认情况下, 进程永远不会异常终止。要指定终止条件, 实现一个回调函数,该函数不接受任何参数,如果 希望堕胎,否则错误。例如,长期以来 进程如果磁盘快满了,您可能要终止它。 但是检查有多少空间是空闲的可能是一个很长的操作,所以您可以 只想节俭地做:
def out_of_diskspace(): left = handytools.check_disk_free() total = handytools.check_disk_total() return (left / total) < 0.03 # The following drainer executes the cruncher and checks whether the disk # is (almost) full every 5 seconds. It aborts if free disk space runs # under 3%. my_drainer = Drainer(['/bin/crunch', 'inputfile', 'outputfile'], read_event_cb=ignore_event, should_abort=out_of_diskspace, check_interval=5.0) exitcode = my_drainer.start()
这个例子很能自我解释。您可以查看ExtCal码以查看 过程的结果。
更多示例
有关更详细的示例,请参见examples目录。