在Python 3.6.5中,这很好:
command = "ffmpeg -i {0} -vsync 0 -q:v 2 -vf select="eq(pict_type,PICT_TYPE_I)" -r 30 {1}/frame%03d.jpg".format(file_path, output_path)
这显然是一条很长的线路,所以我使用了一个线路延续:
command = "ffmpeg -i {0} -vsync 0 -q:v 2 -vf select="eq(pict_type,PICT_TYPE_I)" -r 30 {1}/frame%03d.jpg"
.format(file_path, output_path)
然而,在启动时,这会生成DeprecationWarning
:
DeprecationWarning: invalid escape sequence ,
command = "ffmpeg -i {0} -vsync 0 -q:v 2 -vf select="eq(pict_type,PICT_TYPE_I)" -r 30 {1}/frame%03d.jpg"
这并不是,但是:
command = "foo {0} bar {1}"
.format(file_path, output_path)
我在项目的其余部分都使用了换行符;均未产生CCD_ 2。其他像这个问题提到了这个警告,但我找不到任何关于延续字符的问题。
是什么导致了这种警告,为什么它只出现在这种非常狭窄的情况下?
编辑:这与行的延续无关。这个错误之所以只是部分时间出现在我面前,与Django的runserver
有关。首次运行runserver
时,不会报告错误。但是,如果更改导致重新加载,则在重新加载程序运行时会报告错误。
这与行的延续无关,而是使用,
作为字符串中的转义序列。
警告明确包括,
:
DeprecationWarning: invalid escape sequence ,
这就是为什么后面的例子没有警告:因为字符串中没有,
或其他无法识别的转义序列
如文档中对字符串和字节文字的解释:
3.6版中的更改:无法识别的转义序列会生成
DeprecationWarning
。在未来的Python版本中,它们将是SyntaxError
。
Python 3.6中的新增内容中提到了这一更改,并提供了一个到问题#27364的链接,该链接链接到了之前关于-dev邮件列表的讨论。
传统上,Python允许在字符串文本中使用无法识别的转义序列,并将其视为非转义进行处理,因此,
的字面意思是反斜杠和逗号,因为这使得在调试器中打印字符串时更容易发现问题所在。
但这会导致各种各样的混乱,尤其是对于Windows用户(他们可以使用'C:Spam'
、'C:spam'
和'C:Vikings'
,但使用'C:vikings'
会出错(,以及来自大量遵循C风格转义规则的语言中的任何一种的人(其中,
的意思只是逗号——尽管大多数C编译器都会为此生成警告(,这大概就是你现在收到警告的原因。
尝试使用命令列表:
command = [
"ffmpeg",
"-i", file_path,
"-vsync", "0",
"-q:v", "2",
"-vf", 'select="eq(pict_type,PICT_TYPE_I)"',
"-r", "30",
os.path.join(output_path, "frame%03d.jpg"),
]
然后在不使用shell=True
:的情况下调用它
subprocess.run(command)
通过这样做,您有多种优势:
- 您可以摆脱引号并逃离地狱-您不必添加引号或逃离任何内容。空格不再是分隔符,参数将按列表中的方式传递
- 您不必使用字符串插值(
.format
(,因为您只需将参数单独传递给列表即可 - 通过不使用shell,可以避免白白执行一个额外的进程——既然可以直接运行命令,为什么还要执行shell来运行命令呢