【问题标题】:Good way to count number of functions of a python file, given path给定路径,计算python文件函数数量的好方法
【发布时间】:2016-05-29 20:27:27
【问题描述】:

我不想导入我的模块。我必须计算给定 .py 文件路径的函数数量。最好的方法是什么?

我想到的一件事是计算我的代码中“def”的数量,但这似乎不是解决这个问题的最佳方法。有没有更好的方法来计算函数的数量?

【问题讨论】:

  • 我想说计算def 的出现次数实际上是最好的方法。
  • 你需要包含动态创建的函数吗?如果你做了from math import sin,那会算入文件中的函数数量吗?
  • 没有。只是 def my_function 形式的函数: ...
  • @RobertR 不。我可以想到 2 种情况,其中计数 def 会失败:1)如果有一个包含 def 的字符串 2)如果有一个注释为 def 的块!
  • 如果您不想导入它,您将被限制在您的选项中。否则你可以做len(dir(module)) 和漂亮的事情。但是由于您只能阅读一串内容,因此您必须检查def(

标签: python parsing


【解决方案1】:

要计算顶级定义,请像这样使用ast 模块:

import ast

with open(filename) as f:
    tree = ast.parse(f.read())
    sum(isinstance(exp, ast.FunctionDef) for exp in tree.body)

【讨论】:

    【解决方案2】:

    你可以使用ast.NodeVisitor:

    import inspect
    import importlib
    import ast
    
    class CountFunc(ast.NodeVisitor):
        func_count = 0
        def visit_FunctionDef(self, node):
            self.func_count += 1
    
    
    mod = "/path/to/some.py"
    
    p = ast.parse(open(mod).read())
    
    f = CountFunc()
    f.visit(p)
    
    print(f.func_count)
    

    如果您想包含 lambda,您需要添加 visit_Lambda

     def visit_Lambda(self, node):
        self.func_count += 1
    

    这将找到所有定义,包括任何类的方法,我们可以添加更多限制来禁止:

    class CountFunc(ast.NodeVisitor):
        func_count = 0
    
        def visit_ClassDef(self, node):
            return 
    
        def visit_FunctionDef(self, node):
            self.func_count += 1
    
    
        def visit_Lambda(self, node):
            self.func_count += 1
    

    您可以随意定制代码,所有节点及其属性都在greentreesnakes docs中进行了描述

    【讨论】:

      【解决方案3】:

      Padraic 胜过我,但这是我的代码,适用于 Python 2 和 Python 3。

      from __future__ import print_function
      import ast
      
      class FunctionCounter(ast.NodeVisitor):
          def __init__(self, filename):
              self.function_count = 0
              with open(filename) as f:
                  module = ast.parse(f.read())
                  self.visit(module)
      
          def visit_FunctionDef(self, node):
              print('function: {}'.format(node.name))
              self.function_count += 1
      
          # Uncomment this to disable counting methods, properties within a
          # class
          # def visit_ClassDef(self, node):
          #     pass
      
      if __name__ == '__main__':
          counter = FunctionCounter('simple.py')
          print('Number of functions: {}'.format(counter.function_count))
      

      讨论

      • 此代码不仅计算模块级别的函数,还计算嵌套在类定义中的函数(方法和属性)。
      • 要禁用类定义中的计数功能,请取消注释 visit_ClassDef 的 2 行

      【讨论】:

        【解决方案4】:

        你可以使用

        len(dir(module))
        

        希望对你有帮助

        【讨论】:

        • 如果不先导入module,这将无法工作,对吗?即使最初的问题明显有 x-y 的味道,它确实非常明确地说:“我不想导入我的模块”——因此,我认为我们不能认为这个答案是正确的,特别是因为 2016 年的 cmets 已经明确表示如果不是“禁止导入”约束,这将是一个选项:stackoverflow.com/questions/37514636/…
        • 是的,我们需要先导入模块才能找到这段代码的函数数量!!
        【解决方案5】:

        您可以使用pyclbr 模块来获取模块的结果,唯一的问题是您需要使用模块的名称,因为您将导入它而不是文件路径,这也得益于识别@987654322 @ 用于基于 python 源代码的模块(不是像 math 这样的内置模块)

        from pyclbr import readmodule_ex, Function
        #readmodule_ex is function 1
        
        def test(): #2
            pass
        def other_func(): #3
            pass
        
        class Thing:
            def method(self):
                pass
        
        
        result = readmodule_ex("test") #this would be it's own file if it is test.py
        
        funcs = sum(isinstance(v,Function) for v in result.values())
        
        print(funcs)
        

        【讨论】:

          【解决方案6】:

          我的答案是对@Naveen Kumar 答案的编辑,因为我目前无法编辑他的答案。 你可以使用

          import module
          
          len(dir(module))
          

          即:

          import math
          print(len(dir(math)))
          

          输出:

           63
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-07-16
            • 1970-01-01
            • 2018-09-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多