Python行继续会导致DeprecationWarning

时间:2018-07-25 20:04:05

标签: python django python-3.x

在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)

我在项目的其余部分都使用连续行;没有产生DeprecationWarning的结果。其他类似this one之类的问题都提到了此警告,但对于我可以找到的连续字符却没有提及。

是什么原因导致出现此警告,为什么它仅在这种非常狭窄的情况下出现?

编辑:这与换行无关。该错误仅在某些时候显示给我的原因与Django的runserver有关。第一次运行runserver时,不会报告该错误。但是,如果更改导致重新加载,则在重新加载器运行时会报告错误。

2 个答案:

答案 0 :(得分:4)

这与您的行继续无关,它与使用\,作为字符串中的转义序列有关。

警告明确包含\,

DeprecationWarning: invalid escape sequence \,

这就是为什么您后面的示例不会警告的原因:因为该字符串中没有\,或其他无法识别的转义序列。

String and Byte literals文档中所述:

  

在3.6版中进行了更改:无法识别的转义序列产生DeprecationWarning。在将来的Python版本中,它们将是SyntaxError

What's New in Python 3.6中提到了此更改,其中包含指向issue #27364的链接,该链接也指向an earlier discussion on the -dev mailing list

传统上,Python允许在字符串文字中使用无法识别的转义序列,并像对待非转义一样对其进行处理,因此\,的字面意思是反斜杠和逗号,因为这样可以更轻松地查看发生错误的原因您可以在调试器中打印出字符串。

但这会引起各种混乱,尤其是对于Windows用户(他们放弃了'C:\Spam''C:\spam''C:\Vikings',但遇到了'C:\vikings'的错误) ,并且对于来自遵循C样式转义规则(其中\,仅表示逗号的语言)的人来说,尽管大多数C编译器都会对此发出警告),这大概就是为什么您现在收到警告。

答案 1 :(得分:2)

尝试使用命令列表:

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)

这样做,您有多个优点:

  1. 免于引用并逃脱地狱-您无需添加引号或逃避任何操作。空格不再是定界符,参数将按列表中的方式传递。
  2. 您不必使用字符串插值(.format),因为您只需将参数分别传递到列表即可。
  3. 通过不使用外壳,您可以避免无所事事地执行一个额外的过程-为什么要在直接运行命令时执行命令来运行外壳程序来运行命令?