本文目录导读:

我来详细介绍使用Radon分析Python代码复杂度的方法:
安装Radon
pip install radon
Radon支持的复杂度指标
1 圈复杂度(Cyclomatic Complexity)
衡量代码的分支复杂度
# 示例代码:complex_functions.py
def simple_function(a, b):
return a + b
def complex_function(x, y, z):
if x > 0:
if y > 0:
if z > 0:
return "all positive"
else:
return "z negative"
else:
return "y negative"
else:
return "x negative"
2 认知复杂度(Cognitive Complexity)
衡量代码的理解难度(Radon 4.0+)
命令行使用
1 分析单个文件
# 显示圈复杂度 radon cc complex_functions.py -s # 显示评分(A-F等级) radon cc complex_functions.py -a # 显示详细输出 radon cc complex_functions.py -s -n
2 分析整个项目
# 递归分析所有Python文件 radon cc my_project/ -s # 排除测试文件 radon cc my_project/ -e "test_*.py"
3 按复杂度排序
# 按复杂度降序排列 radon cc my_project/ -s --sort
Python API使用
import radon
from radon.complexity import cc_visit, cc_rank
from radon.raw import analyze
# 读取代码
with open('complex_functions.py', 'r') as f:
code = f.read()
# 分析圈复杂度
results = cc_visit(code)
for func in results:
print(f"Function: {func.name}")
print(f"Complexity: {func.complexity}")
print(f"Rank: {cc_rank(func.complexity)}")
print(f"Line: {func.lineno}")
print("---")
复杂度等级说明
def get_complexity_rank(complexity):
"""圈复杂度等级"""
ranks = {
'A': (1, 5, '低风险'),
'B': (6, 10, '较低风险'),
'C': (11, 20, '中等风险'),
'D': (21, 30, '较高风险'),
'E': (31, 40, '高风险'),
'F': (41, float('inf'), '极高的风险')
}
for rank, (min_val, max_val, desc) in ranks.items():
if min_val <= complexity <= max_val:
return f"{rank}级: {desc}"
return "未知等级"
# 示例
print(get_complexity_rank(3)) # A级
print(get_complexity_rank(15)) # C级
print(get_complexity_rank(50)) # F级
生成HTML报告
import json
from radon.complexity import cc_visit
from radon.raw import analyze
def generate_complexity_report(code, filename):
"""生成可读性报告"""
# 圈复杂度
cc_results = cc_visit(code)
# 原始指标
raw_metrics = analyze(code)
report = {
'file': filename,
'complexity': {
'functions': [],
'average': 0
},
'raw_metrics': {
'lines': raw_metrics.loc,
'code_lines': raw_metrics.sloc,
'comments': raw_metrics.comments,
'docstrings': raw_metrics.multi,
}
}
complexities = []
for func in cc_results:
func_info = {
'name': func.name,
'type': func.type,
'complexity': func.complexity,
'rank': cc_rank(func.complexity),
'line': func.lineno
}
report['complexity']['functions'].append(func_info)
complexities.append(func.complexity)
if complexities:
report['complexity']['average'] = sum(complexities) / len(complexities)
return report
# 使用示例
code = """
def func1(x):
if x > 0:
return x
return -x
def func2(a, b, c):
if a > b:
if b > c:
return a
else:
return c
else:
return b
"""
report = generate_complexity_report(code, 'example.py')
print(json.dumps(report, indent=2))
与其他工具集成
1 集成到测试框架
import pytest
from radon.complexity import cc_visit
def test_complexity():
"""确保代码复杂度不超过阈值"""
MAX_COMPLEXITY = 10
with open('my_module.py', 'r') as f:
code = f.read()
results = cc_visit(code)
for func in results:
assert func.complexity <= MAX_COMPLEXITY, \
f"{func.name} 复杂度 {func.complexity} 超过阈值 {MAX_COMPLEXITY}"
2 集成到CI/CD
# .github/workflows/complexity-check.yml
name: Code Complexity Check
on: [push, pull_request]
jobs:
complexity:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: |
pip install radon
- name: Check complexity
run: |
radon cc . -a --exclude "tests/*,.venv/*"
实际案例分析
# bad_complexity.py - 高复杂度示例
def process_data(data, options):
"""处理数据的高复杂度函数"""
if options.get('validate'):
if not data:
return {'error': 'No data'}
if options.get('type') == 'csv':
if isinstance(data, str):
lines = data.split('\n')
rows = [line.split(',') for line in lines]
if options.get('header'):
if rows:
headers = rows[0]
data = rows[1:]
else:
return {'error': 'Empty CSV'}
else:
headers = None
data = rows
else:
return {'error': 'Invalid CSV format'}
elif options.get('type') == 'json':
import json
try:
if isinstance(data, str):
data = json.loads(data)
if isinstance(data, dict):
if options.get('flatten'):
flattened = {}
for key, value in data.items():
if isinstance(value, dict):
for sub_key, sub_value in value.items():
flattened[f"{key}_{sub_key}"] = sub_value
else:
flattened[key] = value
data = flattened
except json.JSONDecodeError:
return {'error': 'Invalid JSON'}
else:
return {'error': f'Unsupported type: {options.get("type")}'}
# ... 更多条件和循环
return {'result': data}
# 复杂度分析结果
# radon cc bad_complexity.py -s
# 会显示函数复杂度较高
改进高复杂度代码
# good_complexity.py - 重构后的低复杂度代码
class DataProcessor:
"""处理数据类"""
def process(self, data, options):
"""主处理方法"""
if options.get('validate'):
validation_result = self._validate_data(data, options)
if validation_result['error']:
return validation_result
processed_data = self._process_by_type(data, options)
return {'result': processed_data}
def _validate_data(self, data, options):
"""验证数据"""
if not data:
return {'error': 'No data'}
return {'error': None}
def _process_by_type(self, data, options):
"""根据类型处理数据"""
processors = {
'csv': self._process_csv,
'json': self._process_json,
}
processor = processors.get(options.get('type'))
if not processor:
return {'error': f'Unsupported type: {options.get("type")}'}
return processor(data, options)
def _process_csv(self, data, options):
"""处理CSV数据"""
if not isinstance(data, str):
return {'error': 'Invalid CSV format'}
rows = [line.split(',') for line in data.split('\n')]
return self._extract_data(rows, options.get('header'))
def _process_json(self, data, options):
"""处理JSON数据"""
import json
parsed_data = self._parse_json(data)
if parsed_data is None:
return {'error': 'Invalid JSON'}
if options.get('flatten'):
parsed_data = self._flatten_dict(parsed_data)
return parsed_data
# 更多独立的小函数...
最佳实践
1 设置复杂度阈值
# 项目配置
COMPLEXITY_THRESHOLDS = {
'function': 10, # 函数复杂度阈值
'method': 10, # 方法复杂度阈值
'module': 30, # 模块复杂度阈值
}
2 自动化检查
# complexity_checker.py
import os
import sys
from radon.complexity import cc_visit
def check_project_complexity(project_path, max_complexity=10):
"""检查项目复杂度"""
issues = []
for root, dirs, files in os.walk(project_path):
# 跳过隐藏目录和虚拟环境
dirs[:] = [d for d in dirs if not d.startswith('.') and d != 'venv']
for file in files:
if file.endswith('.py'):
filepath = os.path.join(root, file)
with open(filepath, 'r', encoding='utf-8') as f:
try:
results = cc_visit(f.read())
for func in results:
if func.complexity > max_complexity:
issues.append({
'file': filepath,
'function': func.name,
'complexity': func.complexity,
'line': func.lineno
})
except SyntaxError:
print(f"语法错误: {filepath}")
return issues
# 使用
issues = check_project_complexity('./my_project')
if issues:
print("发现高复杂度代码:")
for issue in issues:
print(f" {issue['file']}:{issue['line']} - "
f"{issue['function']}({issue['complexity']})")
else:
print("所有代码复杂度在阈值范围内")
通过以上方法,你可以全面分析Python代码的复杂度,并持续改进代码质量。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播