在 Python 中捕获由 sendpraat 命令产生的 Praat 错误消息
Capture Praat error messages resulting from sendpraat command in Python
您可以启动一个 Praat 实例,然后使用 sendpraat.exe
向它发送 GUI 命令。所以,如果你有 Praat 运行 在后台,下面的命令将导致它在本地 mysound.wav
文件中作为声音对象读取:
sendpraat praat "Read from file... mysound.wav"
并且有很多方法可以通过 Python 发送此命令,例如:
import subprocess
subprocess.call('sendpraat praat "Read from file... mysound.wav"')
但是如果mysound.wav
不存在,Praat实例会弹出一个错误信息框。如何在 Python 中捕获此错误消息的内容并避免弹出窗口?
这些解决方案不适用于问题:
对于这个特定的示例,如果文件存在,我可以只签入 Python。但我还需要处理 Praat 会抛出的所有其他错误,例如当它遇到编码问题或样本被裁剪时。
我可以在命令前使用nocheck
(sendpraat praat nocheck "Read from file... mysound.wav"
来避免弹出,但是Python无法知道命令失败。
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 尝试/捕捉
自从我写下这个答案后,我已经设法实现了 a try/catch procedure for Praat 的一个非常初级的版本。有了它,像
这样的脚本
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
将执行而不会崩溃,留下创建的声音,因为删除它的行没有 运行。
程序在 utils plugin distributed through CPrAN, and is implemented here 中可用。
您可以启动一个 Praat 实例,然后使用 sendpraat.exe
向它发送 GUI 命令。所以,如果你有 Praat 运行 在后台,下面的命令将导致它在本地 mysound.wav
文件中作为声音对象读取:
sendpraat praat "Read from file... mysound.wav"
并且有很多方法可以通过 Python 发送此命令,例如:
import subprocess
subprocess.call('sendpraat praat "Read from file... mysound.wav"')
但是如果mysound.wav
不存在,Praat实例会弹出一个错误信息框。如何在 Python 中捕获此错误消息的内容并避免弹出窗口?
这些解决方案不适用于问题:
对于这个特定的示例,如果文件存在,我可以只签入 Python。但我还需要处理 Praat 会抛出的所有其他错误,例如当它遇到编码问题或样本被裁剪时。
我可以在命令前使用
nocheck
(sendpraat praat nocheck "Read from file... mysound.wav"
来避免弹出,但是Python无法知道命令失败。
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 尝试/捕捉
自从我写下这个答案后,我已经设法实现了 a try/catch procedure for Praat 的一个非常初级的版本。有了它,像
这样的脚本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
将执行而不会崩溃,留下创建的声音,因为删除它的行没有 运行。
程序在 utils plugin distributed through CPrAN, and is implemented here 中可用。