0

您可以启动一个 Praat 实例,然后使用sendpraat.exe它向它发送 GUI 命令。因此,如果您在后台运行 Praat,则以下命令将导致它mysound.wav作为 Sound 对象读入本地文件:

sendpraat praat "Read from file... mysound.wav"

并且有很多方法可以通过 Python 发送此命令,例如:

import subprocess
subprocess.call('sendpraat praat "Read from file... mysound.wav"')

但是如果mysound.wav不存在,Praat 实例会弹出一个带有错误的消息框。如何在 Python 中捕获此错误消息的内容并避免弹出窗口?

这些解决方案不适用于该问题:

  1. 对于这个特定的示例,如果文件存在,我可以只签入 Python。但我还需要处理 Praat 将抛出的所有其他错误,例如当它遇到编码问题时,或者当样本被剪裁时。

  2. 我可以nocheck在命令之前使用 (sendpraat praat nocheck "Read from file... mysound.wav"来避免弹出窗口,但是 Python 无法知道命令失败。

4

1 回答 1

1

nocheck是 Praat 中进行错误处理的唯一方法,尽管它可能是有限的。如果您想从 Python(或任何其他此类)以编程方式使用 GUI,进行错误处理的最佳方法是使用nocheck然后通过查找这些命令的副作用来捕获错误。

如果您正在打开一个Sound,您可以做assert numberOfSelected("Sound")或类似的事情(或多或少优雅的测试)。如果您正在向磁盘写入内容,您可以使用fileReadable()来查看文件是否已创建。

或者,如果您实际上不使用GUI,您可以完全绕过sendpraat并通过控制台使用 Praat(对于 6.0 之前的版本,Windows 需要一个不同的二进制文件praatcon,但最近的版本使用带有--run选项的相同程序)。

您将无法直接将命令传递给它,但您可以将这些命令封装到脚本中,然后执行subprocess.call('praat --run path/to/my/script.praat arguments')或类似的操作。然后,您可能能够使用 Python 捕获该脚本(=您的命令)中的错误,或者实现与上述相同的手动错误检查。

更新:一个例子

这是一个例子(在 Perl 和 Linux 中,但你明白了):

#!/usr/bin/env perl

use Capture::Tiny ':all';
use Try::Tiny;

try {
  ($stdout, $stderr, $exit) = capture {
    system( 'praat', '--run', '~/stdout.praat' );
  }
}
catch {
  chomp;
  warn "It died: $_";
};

print "STDOUT:\n$stdout\n";
print "STDERR:\n$stderr";

和内容stdout.praat

abc$ = "abcde"
num$ = "0123456789"
writeInfoLine: abc$
assert selected("Sound")  ; Fail
writeInfoLine: abc$, num$ ; Won't run

输出:

user@linux:~$ perl stdout.pl
STDOUT:
abcde

STDERR:
Error: No Sound selected.
Formula not run.
Script line 4 not performed or completed:
« assert selected("Sound") ; Fail »
Script “/home/user/stdout.praat” not completed.
Praat: command file “/home/user/stdout.praat” not completed.

更新:在普拉特尝试/捕捉

自从我写了这个答案以来,我已经设法为 Praat 实现了一个非常基本的 try/catch 程序版本。有了它,一个像

include path/to/try.proc

writeInfoLine: "Before fail"

call try
  ... abc$ = "abcde"                                \n
  ... num$ = "0123456789"                           \n
  ... Create Sound as pure tone: "tone",            \n
  ...   ... 1, 0, 0.4, 44100, 440, 0.2, 0.01, 0.01  \n
  ... assert selected("TextGrid")  ; Fail           \n
  ... Remove                       ; Won't run      \n

if try.catch
  appendInfoLine: "Failed!"
endif

将在不崩溃的情况下执行,留下由于删除它的行没有运行而创建的声音。

该过程在通过 CPrAN 分发的utils插件中可用,并在此处实现。

于 2015-09-05T10:41:18.563 回答