专业的编程技术博客社区

网站首页 > 博客文章 正文

Github 13.9k star,一个超Nice的 Python 库-yapf!

baijin 2025-07-24 16:22:53 博客文章 4 ℃ 0 评论

大家好,今天为大家分享一个超Nice的 Python 库 - yapf。

Github地址:https://github.com/google/yapf


在软件开发过程中,代码风格的一致性对于项目的可维护性和团队协作效率具有重要意义。yapf(Yet Another Python Formatter)库作为Google开源的Python代码格式化工具,为开发团队提供了一个高度可配置的代码风格统一解决方案。

yapf库的核心理念是"如果代码在语法上是正确的,那么格式化器应该能够将其重新格式化为符合风格指南的最佳形式"。与其他格式化工具不同,yapf不仅仅是简单地检查和修复风格问题,而是完全重新格式化代码,确保输出结果始终符合预定义的风格标准。

安装

yapf库提供了多种安装方式,支持通过标准的Python包管理工具进行安装。

建议在项目虚拟环境中安装以确保版本兼容性。

# 使用pip安装yapf
pip install yapf

# 安装特定版本
pip install yapf==0.40.2

# 从源码安装最新开发版本
pip install git+https://github.com/google/yapf.git

安装完成后,可以通过以下代码验证安装状态并检查版本信息。

验证过程包括导入库、检查版本以及测试基本的格式化功能:

import yapf
from yapf.yapflib import reformatter
from yapf.yapflib import style

# 检查yapf版本
print("yapf版本:", yapf.__version__)

# 测试基本格式化功能
test_code = "def hello(   name  ):print('Hello, '+name)"
formatted_code = yapf.yapflib.yapf_api.FormatCode(test_code)
print("格式化测试成功:")
print(formatted_code[0])

运行结果:

yapf版本: 0.40.2
格式化测试成功:
def hello(name):
    print('Hello, ' + name)

主要特性

  • 完全重格式化能力:yapf采用完全重写的方式处理代码,而不是简单的规则修复,确保输出结果完全符合风格标准
  • 高度可配置性:支持通过配置文件自定义格式化规则,可以适应不同团队和项目的风格要求
  • 多种预设风格:内置Google、PEP8、Facebook等主流代码风格模板,可直接使用或作为自定义配置的基础
  • 智能断行算法:采用先进的算法决定最佳的代码断行位置,平衡代码可读性和行长度限制
  • 保持语义不变:格式化过程严格保证代码的语义和功能不发生任何改变
  • 集成开发环境支持:提供与主流编辑器和IDE的集成插件,支持实时格式化和保存时自动格式化
  • 命令行工具:提供功能完整的命令行接口,支持批量处理和自动化工作流集成

基本功能

1、基础代码格式化

以下示例展示了yapf的基础格式化功能。这个功能适用于日常开发中的代码整理工作,能够快速将不规范的代码转换为符合标准的格式,显著提升代码的可读性和专业性。

from yapf.yapflib import yapf_api

# 定义需要格式化的代码
unformatted_code = '''
def calculate_average(numbers):
    if len(numbers)==0:return 0
    total=sum(numbers)
    return total/len(numbers)

class DataProcessor:
    def __init__(self,data):
        self.data=data
    def process(self):
        result=[]
        for item in self.data:
            if item>0:result.append(item*2)
        return result
'''

# 使用yapf进行格式化
formatted_result = yapf_api.FormatCode(unformatted_code, style_config='pep8')
formatted_code = formatted_result[0]

print("格式化后的代码:")
print(formatted_code)

# 检查是否有语法错误
was_formatted = formatted_result[1]
print(f"代码是否被修改: {was_formatted}")

运行结果:

格式化后的代码:
def calculate_average(numbers):
    if len(numbers) == 0: return 0
    total = sum(numbers)
    return total / len(numbers)


class DataProcessor:

    def __init__(self, data):
        self.data = data

    def process(self):
        result = []
        for item in self.data:
            if item > 0: result.append(item * 2)
        return result

代码是否被修改: True

2、不同风格的应用

yapf支持多种预定义的代码风格,每种风格都有其特定的应用场景。

以下示例展示了如何应用不同的代码风格,帮助开发团队选择最适合项目需求的格式化标准。

from yapf.yapflib import yapf_api


def demonstrate_different_styles():
    """演示不同代码风格的格式化效果"""

    sample_code = '''
def process_data(input_list, filter_func=None, transform_func=lambda x: x, output_format='list'):
    filtered_data = [item for item in input_list if filter_func is None or filter_func(item)]
    transformed_data = [transform_func(item) for item in filtered_data]
    if output_format == 'dict': return {i: value for i, value in enumerate(transformed_data)}
    return transformed_data
'''

    styles = ['pep8', 'google', 'facebook']

    for style in styles:
        print(f"\n=== {style.upper()} 风格 ===")
        formatted_result = yapf_api.FormatCode(sample_code, style_config=style)
        print(formatted_result[0])

        # 分析格式化差异
        lines = formatted_result[0].split('\n')
        print(f"总行数: {len([line for line in lines if line.strip()])}")
        print(f"最长行长度: {max(len(line) for line in lines if line.strip())}")


# 执行风格对比
demonstrate_different_styles()

运行结果:


=== PEP8 风格 ===
def process_data(input_list,
                 filter_func=None,
                 transform_func=lambda x: x,
                 output_format='list'):
    filtered_data = [
        item for item in input_list if filter_func is None or filter_func(item)
    ]
    transformed_data = [transform_func(item) for item in filtered_data]
    if output_format == 'dict':
        return {i: value for i, value in enumerate(transformed_data)}
    return transformed_data

总行数: 11
最长行长度: 79

=== GOOGLE 风格 ===
def process_data(input_list,
                 filter_func=None,
                 transform_func=lambda x: x,
                 output_format='list'):
    filtered_data = [
        item for item in input_list if filter_func is None or filter_func(item)
    ]
    transformed_data = [transform_func(item) for item in filtered_data]
    if output_format == 'dict':
        return {i: value for i, value in enumerate(transformed_data)}
    return transformed_data

总行数: 11
最长行长度: 79

=== FACEBOOK 风格 ===
def process_data(
    input_list,
    filter_func=None,
    transform_func=lambda x: x,
    output_format='list'
):
    filtered_data = [
        item for item in input_list if filter_func is None or filter_func(item)
    ]
    transformed_data = [transform_func(item) for item in filtered_data]
    if output_format == 'dict':
        return {i: value for i, value in enumerate(transformed_data)}
    return transformed_data

总行数: 13
最长行长度: 79

3、文件批量处理

在实际项目中,通常需要对多个Python文件进行批量格式化。

以下示例展示了如何使用yapf进行文件级别的格式化操作,这对于大型项目的代码标准化非常有用。

import os
from yapf.yapflib import yapf_api

def batch_format_files(directory_path, style='pep8', backup=True):
    """批量格式化指定目录下的Python文件"""
    
    formatted_files = []
    error_files = []
    
    # 遍历目录查找Python文件
    for root, dirs, files in os.walk(directory_path):
        for file in files:
            if file.endswith('.py'):
                file_path = os.path.join(root, file)
                
                try:
                    # 读取原始文件内容
                    with open(file_path, 'r', encoding='utf-8') as f:
                        original_content = f.read()
                    
                    # 进行格式化
                    formatted_result = yapf_api.FormatCode(
                        original_content, 
                        style_config=style
                    )
                    formatted_content = formatted_result[0]
                    was_changed = formatted_result[1]
                    
                    if was_changed:
                        # 创建备份文件
                        if backup:
                            backup_path = file_path + '.bak'
                            with open(backup_path, 'w', encoding='utf-8') as f:
                                f.write(original_content)
                        
                        # 写入格式化后的内容
                        with open(file_path, 'w', encoding='utf-8') as f:
                            f.write(formatted_content)
                        
                        formatted_files.append(file_path)
                        print(f"已格式化: {file_path}")
                    
                except Exception as e:
                    error_files.append((file_path, str(e)))
                    print(f"格式化失败: {file_path} - {e}")
    
    # 返回处理结果统计
    return {
        'formatted_count': len(formatted_files),
        'error_count': len(error_files),
        'formatted_files': formatted_files,
        'error_files': error_files
    }

# 示例用法
# result = batch_format_files('./my_project', style='google', backup=True)
# print(f"成功格式化 {result['formatted_count']} 个文件")

高级功能

1、自定义配置文件

yapf支持通过配置文件进行高度定制化的格式化设置。自定义配置允许团队根据特定的编码规范和偏好调整格式化行为,确保代码风格完全符合项目要求。

from yapf.yapflib import yapf_api


def create_custom_yapf_config():
    """创建自定义yapf配置文件"""

    # 定义自定义配置内容
    custom_config = """
[style]
# 基于Google风格进行自定义
based_on_style = google

# 列宽设置
column_limit = 88

# 缩进设置
indent_width = 4
continuation_indent_width = 4

# 空行设置
blank_line_before_nested_class_or_def = true
blank_lines_around_top_level_definition = 2

# 字符串格式化
dedent_closing_brackets = true
indent_closing_brackets = false

# 函数调用格式化
allow_multiline_lambdas = true
coalesce_brackets = true

# 注释格式化
spaces_before_comment = 2

# 字典和列表格式化
allow_multiline_dictionary_keys = false
indent_dictionary_value = true
"""

    # 写入配置文件
    config_path = '.style.yapf'
    with open(config_path, 'w', encoding='utf-8') as f:
        f.write(custom_config)

    print(f"自定义配置文件已创建: {config_path}")

    # 测试自定义配置
    test_code = '''
def complex_function(param1, param2, param3="default", param4=None):
    """This is a complex function with multiple parameters."""
    data = {"key1": "value1", "key2": "value2", "key3": "value3"}
    result = [item for item in data.items() if item[1] is not None]
    return result
'''

    # 使用自定义配置格式化
    formatted_result = yapf_api.FormatCode(test_code, style_config=config_path)
    print("使用自定义配置格式化的结果:")
    print(formatted_result[0])

    return config_path


# 创建并测试自定义配置
custom_config_path = create_custom_yapf_config()

运行结果:

自定义配置文件已创建: .style.yapf
使用自定义配置格式化的结果:
def complex_function(param1, param2, param3="default", param4=None):
    """This is a complex function with multiple parameters."""
    data = {"key1": "value1", "key2": "value2", "key3": "value3"}
    result = [item for item in data.items() if item[1] is not None]
    return result

2、与开发工具集成

yapf可以与各种开发工具和工作流程集成,实现自动化的代码格式化。

以下示例展示了如何在不同场景下集成yapf,提升开发效率。

import os
import subprocess
import sys
import json


def setup_git_hooks():
    """设置Git钩子实现提交前自动格式化"""

    pre_commit_hook = '''#!/bin/bash
# Git pre-commit hook for yapf formatting

echo "Running yapf formatter..."

# 获取待提交的Python文件
python_files=$(git diff --cached --name-only --diff-filter=ACM | grep -E "\.py#34;)

if [ -z "$python_files" ]; then
    echo "No Python files to format."
    exit 0
fi

# 对每个文件运行yapf
for file in $python_files; do
    echo "Formatting $file"
    yapf --in-place --style=pep8 "$file"
    git add "$file"
done

echo "Code formatting completed."
'''

    # 写入pre-commit钩子
    hook_path = '.git/hooks/pre-commit'
    with open(hook_path, 'w') as f:
        f.write(pre_commit_hook)

    # 设置执行权限
    os.chmod(hook_path, 0o755)
    print("Git pre-commit hook 已设置")


def integrate_with_ci_cd():
    """CI/CD集成示例配置"""

    # GitHub Actions配置示例
    github_action = {
        "name": "Code Style Check",
        "on": ["push", "pull_request"],
        "jobs": {
            "yapf-check": {
                "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 yapf",
                        "run": "pip install yapf"
                    },
                    {
                        "name": "Check code formatting",
                        "run": "yapf --diff --recursive ."
                    }
                ]
            }
        }
    }

    # 写入GitHub Actions配置
    os.makedirs('.github/workflows', exist_ok=True)
    with open('.github/workflows/code-style.yml', 'w') as f:
        import yaml
        yaml.dump(github_action, f, default_flow_style=False)

    print("GitHub Actions配置已创建")


def create_vscode_settings():
    """创建VS Code集成配置"""

    vscode_settings = {
        "python.formatting.provider": "yapf",
        "python.formatting.yapfArgs": ["--style=pep8"],
        "editor.formatOnSave": True,
        "editor.formatOnPaste": True,
        "[python]": {
            "editor.codeActionsOnSave": {
                "source.organizeImports": True
            }
        }
    }

    # 创建VS Code设置目录
    os.makedirs('.vscode', exist_ok=True)
    with open('.vscode/settings.json', 'w') as f:
        json.dump(vscode_settings, f, indent=4)

    print("VS Code设置已创建")

# 执行集成配置
setup_git_hooks()
integrate_with_ci_cd()
create_vscode_settings()

总结

yapf库作为专业级的Python代码格式化工具,为软件开发团队提供了一个可靠且高度可配置的代码风格统一解决方案。通过完全重格式化的方式和智能的断行算法,yapf确保了代码格式化结果的一致性和高质量。该库的核心优势在于其灵活的配置能力和广泛的集成支持,能够适应不同规模和类型的项目需求,从基础的代码整理到复杂的企业级开发流程集成,yapf都提供了完整的解决方案,丰富的预设风格和自定义配置选项使得团队能够建立符合自身需求的代码规范。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表