最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python代碼質(zhì)量之從規(guī)范到自動化檢查全過程

 更新時間:2026年05月07日 09:15:03   作者:牧碼人王木木  
本文介紹了提高Python代碼質(zhì)量的十個關(guān)鍵方面,包括清晰的命名、一致性、注釋、模塊化、錯誤處理、測試、代碼簡潔、版本控制、性能優(yōu)化和文檔編寫,需要的朋友可以參考下

1. 技術(shù)分析

1.1 代碼質(zhì)量維度

維度描述工具
代碼風格PEP 8規(guī)范black, isort
類型檢查類型注解檢查mypy
代碼規(guī)范最佳實踐flake8, pylint
安全檢查潛在漏洞bandit, safety
測試覆蓋代碼測試比例coverage

1.2 工具對比

工具功能性能學習曲線
black代碼格式化
flake8代碼檢查
mypy類型檢查
pylint全面檢查
ruff快速linting極快

2. 核心功能實現(xiàn)

2.1 代碼格式化配置

# pyproject.toml
[tool.black]
line-length = 88
target-version = ['py39', 'py310', 'py311']
include = '\.pyi?$'
exclude = '''
/(
    \.git
    | \.venv
    | build
    | dist
)/
'''
[tool.isort]
profile = "black"
line_length = 88
known_first_party = ["src"]
skip = [".venv", "build", "dist"]
[tool.mypy]
python_version = "3.9"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = false
ignore_missing_imports = true
[tool.ruff]
line-length = 88
target-version = "py39"
[tool.ruff.lint]
select = ["E", "F", "W", "I", "N", "UP", "B", "C4"]
ignore = ["E501"]  # 行長度由black處理
[tool.coverage.run]
source = ["src"]
omit = ["*/tests/*", "*/test_*.py"]
[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "if __name__ == .__main__.:",
    "raise AssertionError()",
]

2.2 單元測試實踐

import pytest
from typing import List, Optional

class DataValidator:
    """數(shù)據(jù)驗證器"""
    
    @staticmethod
    def validate_email(email: str) -> bool:
        """驗證郵箱格式"""
        import re
        pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
        return bool(re.match(pattern, email))
    
    @staticmethod
    def validate_positive(value: float) -> bool:
        """驗證正數(shù)"""
        return value > 0
    
    @staticmethod
    def validate_in_range(value: float, min_val: float, max_val: float) -> bool:
        """驗證范圍"""
        return min_val <= value <= max_val

class TestDataValidator:
    """數(shù)據(jù)驗證器測試"""
    
    @pytest.mark.parametrize("email,expected", [
        ("test@example.com", True),
        ("user.name@domain.co.uk", True),
        ("invalid-email", False),
        ("@domain.com", False),
        ("user@", False),
        ("", False),
    ])
    def test_validate_email(self, email, expected):
        assert DataValidator.validate_email(email) == expected
    
    @pytest.mark.parametrize("value,expected", [
        (1.0, True),
        (0.0, False),
        (-1.0, False),
        (100.5, True),
    ])
    def test_validate_positive(self, value, expected):
        assert DataValidator.validate_positive(value) == expected
    
    def test_validate_in_range(self):
        assert DataValidator.validate_in_range(5, 0, 10) == True
        assert DataValidator.validate_in_range(0, 0, 10) == True
        assert DataValidator.validate_in_range(10, 0, 10) == True
        assert DataValidator.validate_in_range(-1, 0, 10) == False
        assert DataValidator.validate_in_range(11, 0, 10) == False

class TestEdgeCases:
    """邊界情況測試"""
    
    def test_empty_string(self):
        assert DataValidator.validate_email("") == False
    
    def test_unicode_email(self):
        assert DataValidator.validate_email("用戶@例子.廣告") == False
    
    def test_very_long_email(self):
        long_email = "a" * 100 + "@example.com"
        # 應該能處理但可能返回False(取決于具體實現(xiàn))
        result = DataValidator.validate_email(long_email)
        assert isinstance(result, bool)

2.3 Mock與測試隔離

from unittest.mock import Mock, patch, MagicMock
import pytest

class APIClient:
    """API客戶端"""
    
    def __init__(self, base_url: str):
        self.base_url = base_url
        self.session = None
    
    def fetch(self, endpoint: str) -> dict:
        """獲取數(shù)據(jù)"""
        import requests
        response = requests.get(f"{self.base_url}/{endpoint}")
        return response.json()

class TestAPIClient:
    """API客戶端測試"""
    
    @patch('requests.get')
    def test_fetch_success(self, mock_get):
        """測試成功獲取"""
        mock_response = Mock()
        mock_response.json.return_value = {"status": "success", "data": [1, 2, 3]}
        mock_get.return_value = mock_response
        
        client = APIClient("https://api.example.com")
        result = client.fetch("users")
        
        assert result["status"] == "success"
        assert result["data"] == [1, 2, 3]
        mock_get.assert_called_once_with("https://api.example.com/users")
    
    @patch('requests.get')
    def test_fetch_error(self, mock_get):
        """測試獲取失敗"""
        mock_get.side_effect = ConnectionError("Network error")
        
        client = APIClient("https://api.example.com")
        
        with pytest.raises(ConnectionError):
            client.fetch("users")
    
    def test_with_fixture(self, mock_get):
        """使用fixture的測試"""
        # fixture在conftest.py中定義
        result = self.client.fetch("users")
        assert "status" in result

2.4 性能測試

import pytest
import time

class TestPerformance:
    """性能測試"""
    
    def test_sort_performance(self):
        """測試排序性能"""
        import random
        
        # 生成大量數(shù)據(jù)
        data = [random.randint(0, 10000) for _ in range(10000)]
        
        start = time.perf_counter()
        sorted_data = sorted(data)
        elapsed = time.perf_counter() - start
        
        # 應該在1秒內(nèi)完成
        assert elapsed < 1.0, f"排序耗時 {elapsed:.2f}s,超過1秒"
        
        # 驗證排序正確性
        assert sorted_data == sorted(data)
    
    @pytest.mark.benchmark
    def test_list_comprehension_performance(self, benchmark):
        """基準測試列表推導式"""
        result = benchmark(lambda: [i**2 for i in range(10000)])
        assert len(result) == 10000

# conftest.py
def pytest_configure(config):
    config.addinivalue_line("markers", "benchmark: mark test as a benchmark")

@pytest.fixture
def sample_data():
    """示例數(shù)據(jù)fixture"""
    return [i for i in range(100)]

3. 持續(xù)集成配置

3.1 pre-commit配置

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-added-large-files
      - id: check-merge-conflict
  - repo: https://github.com/psf/black
    rev: 23.3.0
    hooks:
      - id: black
        language_version: python3.10
  - repo: https://github.com/pycqa/isort
    rev: 5.12.0
    hooks:
      - id: isort
        args: ["--profile", "black"]
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.0.261
    hooks:
      - id: ruff
        args: ["--fix"]
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.3.0
    hooks:
      - id: mypy
        additional_dependencies: [types-all]

3.2 GitHub Actions CI

# .github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.9', '3.10', '3.11']
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -e ".[dev]"
      - name: Lint with ruff
        run: ruff check src/
      - name: Format check with black
        run: black --check src/
      - name: Type check with mypy
        run: mypy src/
      - name: Test with pytest
        run: |
          coverage run -m pytest tests/
          coverage report --fail-under=80
      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage.xml

4. 代碼質(zhì)量指標

4.1 覆蓋率報告

# 運行測試并生成覆蓋率報告
$ coverage run -m pytest tests/
$ coverage report -m

Name                 Stmts   Miss  Cover   Missing
-----------------------------------------------------
src/validators.py       45      5    89%    23,45,67
src/models.py           78     12    85%    34,56,78
tests/test_validators.py  60      0   100%    -
-----------------------------------------------------
TOTAL                 183     17    91%

4.2 復雜度分析

# 使用radon進行復雜度分析
from radon.metrics import mi_visit, h_visit
from radon.complexity import cc_visit

def analyze_complexity(filepath: str):
    """代碼復雜度分析"""
    with open(filepath, 'r') as f:
        source = f.read()
    
    # 圈復雜度
    complexity = cc_visit(source)
    print("圈復雜度:")
    for item in complexity:
        if item.classname:
            name = f"{item.classname}.{item.name}"
        else:
            name = item.name
        print(f"  {name}: {item.complexity}")
    
    # 維護性指數(shù)
    mi = mi_visit(source, multi=True)
    print(f"\n維護性指數(shù): {mi:.1f}")
    
    # Halstead指標
    from radon.metrics import h_visit
    halstead = h_visit(source)
    print(f"難度: {halstead.difficulty:.1f}")

5. 最佳實踐

5.1 代碼審查清單

- [ ] 代碼符合PEP 8規(guī)范
- [ ] 函數(shù)和類有docstring
- [ ] 類型注解完整
- [ ] 單元測試覆蓋關(guān)鍵邏輯
- [ ] 沒有硬編碼的魔法數(shù)字
- [ ] 錯誤處理適當
- [ ] 沒有安全漏洞
- [ ] 性能符合要求

5.2 提交前檢查

#!/bin/bash
# pre-commit-check.sh
set -e
echo "運行代碼檢查..."
# 格式化
black --check src/
echo "? 格式化檢查通過"
# 檢查import
isort --check-only --diff src/
echo "? import檢查通過"
# Lint
ruff check src/
echo "? Lint檢查通過"
# 類型檢查
mypy src/
echo "? 類型檢查通過"
# 測試
pytest tests/ -v
echo "? 測試通過"
echo "所有檢查通過!"

6. 總結(jié)

代碼質(zhì)量保障要點:

  1. 自動化:使用pre-commit和CI/CD自動化檢查
  2. 覆蓋率:保持80%+的測試覆蓋率
  3. 持續(xù)改進:定期審視和改進代碼質(zhì)量

到此這篇關(guān)于Python代碼質(zhì)量之從規(guī)范到自動化檢查全過程的文章就介紹到這了,更多相關(guān)Python代碼質(zhì)量內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python代碼中引用已經(jīng)寫好的模塊、方法的兩種方式

    Python代碼中引用已經(jīng)寫好的模塊、方法的兩種方式

    這篇文章主要介紹了Python代碼中引用已經(jīng)寫好的模塊、方法,下面就介紹兩種方式,可以簡潔明了地調(diào)用自己在其他模塊寫的代碼,需要的朋友可以參考下
    2022-07-07
  • python實現(xiàn)簡單遺傳算法

    python實現(xiàn)簡單遺傳算法

    這篇文章主要介紹了python如何實現(xiàn)簡單遺傳算法,幫助大家更好的利用python進行數(shù)據(jù)分析,感興趣的朋友可以了解下
    2020-09-09
  • 關(guān)于Python中兩個不同shape的數(shù)組間運算規(guī)則

    關(guān)于Python中兩個不同shape的數(shù)組間運算規(guī)則

    這篇文章主要介紹了關(guān)于Python中兩個不同shape的數(shù)組間運算規(guī)則,眾所周知,相同?shape?的兩個數(shù)組間運算是指兩個數(shù)組的對應元素相加,我們經(jīng)常會碰到一些不同?shape?的數(shù)組間運算,需要的朋友可以參考下
    2023-08-08
  • Python學習筆記之圖片人臉檢測識別實例教程

    Python學習筆記之圖片人臉檢測識別實例教程

    這篇文章主要給大家介紹了關(guān)于Python學習筆記之圖片人臉檢測識別的相關(guān)資料,文中通過示例代碼以及圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-03-03
  • 使用Python實現(xiàn)全攝像頭拍照與鍵盤輸入監(jiān)聽功能

    使用Python實現(xiàn)全攝像頭拍照與鍵盤輸入監(jiān)聽功能

    這篇文章主要介紹了使用Python實現(xiàn)全攝像頭拍照與鍵盤輸入監(jiān)聽功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • 零基礎(chǔ)學Python之前需要學c語言嗎

    零基礎(chǔ)學Python之前需要學c語言嗎

    在本篇文章里小編給大家整理的是一篇關(guān)于零基礎(chǔ)學Python之前需要學c語言關(guān)系的文章,需要的朋友們可以參考下。
    2020-07-07
  • python-opencv-cv2.threshold()二值化函數(shù)的使用

    python-opencv-cv2.threshold()二值化函數(shù)的使用

    這篇文章主要介紹了python-opencv-cv2.threshold()二值化函數(shù)的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 基于Python和OpenCV實現(xiàn)實時文檔掃描的全流程

    基于Python和OpenCV實現(xiàn)實時文檔掃描的全流程

    在日常工作與學習中,我們經(jīng)常需要將紙質(zhì)文檔轉(zhuǎn)化為電子版本,所以本文將詳細講解如何基于 Python 和 OpenCV 構(gòu)建實時文檔掃描系統(tǒng),涵蓋圖像預處理、輪廓檢測、透視變換、二值化等核心步驟,需要的朋友可以參考下
    2025-09-09
  • Python下Fabric的簡單部署方法

    Python下Fabric的簡單部署方法

    這篇文章主要介紹了Python下Fabric的簡單部署方法,Fabric是Python下一個流行的自動化工具,需要的朋友可以參考下
    2015-07-07
  • python使用正則表達式提取網(wǎng)頁URL的方法

    python使用正則表達式提取網(wǎng)頁URL的方法

    這篇文章主要介紹了python使用正則表達式提取網(wǎng)頁URL的方法,涉及Python中urllib模塊及正則表達式的相關(guān)使用技巧,需要的朋友可以參考下
    2015-05-05

最新評論

和田县| 龙里县| 水富县| 泾源县| 游戏| 安龙县| 芜湖县| 旌德县| 西乡县| 平遥县| 长丰县| 通河县| 江源县| 盐池县| 浏阳市| 响水县| 海安县| 平武县| 外汇| 光泽县| 遂昌县| 陆河县| 黄大仙区| 墨竹工卡县| 山阴县| 南丰县| 文水县| 祁门县| 原阳县| 从化市| 阿合奇县| 大余县| 南平市| 新昌县| 逊克县| 菏泽市| 小金县| 南乐县| 丰原市| 宜章县| 清原|