【问题标题】:How can I check the syntax of Python script without executing it?如何在不执行 Python 脚本的情况下检查它的语法?
【发布时间】:2011-05-16 02:53:24
【问题描述】:

我曾经使用perl -c programfile 来检查 Perl 程序的语法,然后不执行就退出。有没有等效的方法来为 Python 脚本执行此操作?

【问题讨论】:

    标签: python compilation syntax-checking


    【解决方案1】:
    python -m compileall -q .
    

    将递归编译当前目录下的所有内容,并且只打印错误。

    $ python -m compileall --help
    usage: compileall.py [-h] [-l] [-r RECURSION] [-f] [-q] [-b] [-d DESTDIR] [-x REGEXP] [-i FILE] [-j WORKERS] [--invalidation-mode {checked-hash,timestamp,unchecked-hash}] [FILE|DIR [FILE|DIR ...]]
    
    Utilities to support installing Python libraries.
    
    positional arguments:
      FILE|DIR              zero or more file and directory names to compile; if no arguments given, defaults to the equivalent of -l sys.path
    
    optional arguments:
      -h, --help            show this help message and exit
      -l                    don't recurse into subdirectories
      -r RECURSION          control the maximum recursion level. if `-l` and `-r` options are specified, then `-r` takes precedence.
      -f                    force rebuild even if timestamps are up to date
      -q                    output only error messages; -qq will suppress the error messages as well.
      -b                    use legacy (pre-PEP3147) compiled file locations
      -d DESTDIR            directory to prepend to file paths for use in compile-time tracebacks and in runtime tracebacks in cases where the source file is unavailable
      -x REGEXP             skip files matching the regular expression; the regexp is searched for in the full path of each file considered for compilation
      -i FILE               add all the files and directories listed in FILE to the list considered for compilation; if "-", names are read from stdin
      -j WORKERS, --workers WORKERS
                            Run compileall concurrently
      --invalidation-mode {checked-hash,timestamp,unchecked-hash}
                            set .pyc invalidation mode; defaults to "checked-hash" if the SOURCE_DATE_EPOCH environment variable is set, and "timestamp" otherwise.
    

    发现语法错误时退出值为 1。

    感谢 C2H5OH。

    【讨论】:

      【解决方案2】:

      感谢以上答案@Rosh Oxymoron。我改进了脚本以扫描目录中所有 python 文件的文件。所以对于我们这些懒惰的人来说,只要给它目录,它就会扫描该目录中的所有 python 文件。

      import sys
      import glob, os
      
      os.chdir(sys.argv[1])
      for file in glob.glob("*.py"):
          source = open(file, 'r').read() + '\n'
          compile(source, file, 'exec')
      

      Save this as checker.py and run python checker.py ~/YOURDirectoryTOCHECK

      【讨论】:

        【解决方案3】:

        Pyflakes 会按照您的要求执行,它只是检查语法。来自文档:

        Pyflakes 做出一个简单的承诺:它永远不会抱怨风格,并且会非常非常努力地从不发出误报。

        Pyflakes 也比 Pylint 或 Pychecker 更快。这主要是因为 Pyflakes 只单独检查每个文件的语法树。

        安装和使用:

        $ pip install pyflakes
        $ pyflakes yourPyFile.py
        

        【讨论】:

        • 这比大多数投票的答案要好。它不仅检查语法,还显示所有未使用和未定义的变量。非常有用,尤其是在您运行脚本时。
        【解决方案4】:

        这是另一个解决方案,使用 ast 模块:

        python -c "import ast; ast.parse(open('programfile').read())"
        

        在 Python 脚本中干净利落地完成:

        import ast, traceback
        
        filename = 'programfile'
        with open(filename) as f:
            source = f.read()
        valid = True
        try:
            ast.parse(source)
        except SyntaxError:
            valid = False
            traceback.print_exc()  # Remove to silence any errros
        print(valid)
        

        【讨论】:

        • 很棒的单行程序,不需要所有导入的库或生成 .pyc 文件。谢谢!
        • 应该是公认的答案。当人们只想知道语法是否有效时,编译这些文件(正如公认的答案所暗示的那样)是多余的。
        • 注意ast.parse(string)equivalent to compile(string, filename='<unknown>', mode='exec', flags=ast.PyCF_ONLY_AST)
        • 正是我想做的。
        【解决方案5】:

        由于某种原因(我是 py 新手...) -m 调用不起作用...

        所以这里是一个 bash 包装函数 ...

        # ---------------------------------------------------------
        # check the python synax for all the *.py files under the
        # <<product_version_dir/sfw/python
        # ---------------------------------------------------------
        doCheckPythonSyntax(){
        
            doLog "DEBUG START doCheckPythonSyntax"
        
            test -z "$sleep_interval" || sleep "$sleep_interval"
            cd $product_version_dir/sfw/python
            # python3 -m compileall "$product_version_dir/sfw/python"
        
            # foreach *.py file ...
            while read -r f ; do \
        
                py_name_ext=$(basename $f)
                py_name=${py_name_ext%.*}
        
                doLog "python3 -c \"import $py_name\""
                # doLog "python3 -m py_compile $f"
        
                python3 -c "import $py_name"
                # python3 -m py_compile "$f"
                test $! -ne 0 && sleep 5
        
            done < <(find "$product_version_dir/sfw/python" -type f -name "*.py")
        
            doLog "DEBUG STOP  doCheckPythonSyntax"
        }
        # eof func doCheckPythonSyntax
        

        【讨论】:

          【解决方案6】:

          您可以使用这些工具:

          【讨论】:

          • 所有这些都不仅仅是检查语法。真的这不是答案。
          • 所有这些都检查语法,所以答案是正确的。其他检查是(非常有用的)奖励。
          【解决方案7】:

          也许有用的在线检查器 PEP8 :http://pep8online.com/

          【讨论】:

            【解决方案8】:
            import sys
            filename = sys.argv[1]
            source = open(filename, 'r').read() + '\n'
            compile(source, filename, 'exec')
            

            将其保存为 checker.py 并运行 python checker.py yourpyfile.py

            【讨论】:

            • 对于一个小型脚本集合的 Makefile 来说有点太重了,但它可以完成工作并且不会产生任何不需要的文件。
            • 这是一个旧答案,但需要注意的是,这仅检查语法,而不是脚本是否成功执行。
            • 非常感谢。有用。只有一条评论,如果代码正确,则没有答案。否则会显示带有行号的错误消息。
            【解决方案9】:

            你可以通过编译来检查语法:

            python -m py_compile script.py
            

            【讨论】:

            • import script,但所有代码都必须在函数中。无论如何,这是一个很好的做法。我什至将它用于 shell 脚本。从这里开始,这是单元测试的一小步。
            • python -m compileall 也可以递归做目录,并且有更好的命令行界面。
            • 很好的答案,但是如何防止它创建“.pyc”文件?对了,“.pyc”文件有什么用?
            • 对于 Python 2.7.9,当存在 -m py_compile 时,我发现 -BPYTHONDONTWRITEBYTECODE 都不会抑制 .pyc 文件的创建。
            • 我运行了脚本python -m py_compile src/nike_run.py,它在没有错误消息的情况下完成,但代码将在运行时崩溃并显示消息'TypeError:run_test_in_batch()缺少1个必需的位置参数:'total_test_rownum'' ,似乎无法检测到此类错误。如有错误请指正。
            猜你喜欢
            • 2015-12-05
            • 1970-01-01
            • 2010-09-15
            • 2010-09-17
            • 1970-01-01
            • 2018-08-29
            • 1970-01-01
            • 2011-06-26
            相关资源
            最近更新 更多