You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何统计Python程序中的独立Token数量?求相关工具推荐

统计代码独立Token数量的实现方案及跨语言工具

Python 实现方案

用标准库 tokenize 直接统计Token

Python自带的tokenize模块是最简便的Token统计方案,它能精准解析代码的词法单元,还可以过滤掉注释、空白等非业务相关的Token。

以下是可直接运行的脚本:

import tokenize
from io import BytesIO

def count_valid_tokens(code: str) -> int:
    # 将代码转为字节流适配tokenize输入格式
    byte_code = code.encode('utf-8')
    # 生成所有Token
    tokens = list(tokenize.tokenize(BytesIO(byte_code).readline))
    
    # 定义需要统计的有效Token类型(可根据需求调整)
    valid_types = {
        tokenize.NAME, tokenize.NUMBER, tokenize.STRING,
        tokenize.OP, tokenize.NEWLINE, tokenize.INDENT, tokenize.DEDENT
    }
    
    return sum(1 for tok in tokens if tok.type in valid_types)

# 测试你给出的示例代码
sample_code = 'grammar = grammar_path.read_text(encoding="UTF-8")'
print(count_valid_tokens(sample_code))

注:这段代码统计的标准Token数为10(对应每个独立词法单元),如果你需要更粗粒度的统计(比如把grammar_path.read_text合并为一个单元),可以在Token遍历逻辑中添加合并规则,比如连续的NAME+.+NAME视为一个整体。

AST 辅助方案(适用于更抽象的代码单元统计)

如果你需要统计的是语法级别的单元而非纯Token,Python的ast模块可以解析代码生成抽象语法树,遍历节点统计语句、函数调用等单元,但它不直接对应Token级别的计数,适合更宏观的复杂度分析。

其他语言的同类工具

  • JavaScript/TypeScript:使用acorn或@babel/parser,两者都能生成Token流并统计。示例(acorn):
    const acorn = require('acorn');
    const code = `const grammar = grammarPath.readText({encoding: "UTF-8"});`;
    const tokens = acorn.tokenize(code);
    // 过滤空白和注释后统计
    const validCount = tokens.filter(t => t.type !== 'whitespace' && t.type !== 'comment').length;
    console.log(validCount);
    
  • Java:可以用JDK自带的java.io.StreamTokenizer做基础Token统计,复杂场景用ANTLR生成定制化的词法解析器,精准控制Token规则。
  • C/C++:借助clang的API实现Token扫描,或用flex生成自定义词法分析器;也有轻量工具如token-count直接统计。
  • Go:用标准库go/scanner扫描代码生成Token,过滤无效类型后计数:
    package main
    
    import (
        "fmt"
        "go/scanner"
        "go/token"
    )
    
    func countTokens(code string) int {
        var s scanner.Scanner
        fset := token.NewFileSet()
        file := fset.AddFile("", fset.Base(), len(code))
        s.Init(file, []byte(code), nil, scanner.ScanComments)
        count := 0
        for {
            _, tok, _ := s.Scan()
            if tok == token.EOF {
                break
            }
            if tok != token.COMMENT && tok != token.WHITESPACE {
                count++
            }
        }
        return count
    }
    
    func main() {
        code := `grammar := grammarPath.ReadText("UTF-8")`
        fmt.Println(countTokens(code))
    }
    
  • Ruby:用自带的Ripper模块做词法分析,过滤注释和空白后统计Token:
    require 'ripper'
    
    def count_tokens(code)
      tokens = Ripper.lex(code)
      tokens.reject { |t| [:on_comment, :on_sp, :on_nl].include?(t[1]) }.size
    end
    
    sample_code = 'grammar = grammar_path.read_text(encoding: "UTF-8")'
    puts count_tokens(sample_code)
    

内容的提问来源于stack exchange,提问作者Brendan Langfield

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 01:20:42