3、Python基础回顾:变量与数据类型、控制流、函数与装饰器、类与继承

好,咱们直接开工。这一章我把它当成“温润的快速复习”。如果你已经写过一阵Python,可能会觉得某些内容太简单。但别急,我故意挑了一些我当年踩过的坑,还有质控工具里高频出现的写法。你花20分钟过一遍,后面实战的时候会顺很多。

3.1 变量与数据类型

Python是动态类型语言。变量的类型在赋值那一刻才确定,之后再换类型也不报错。这很灵活,但也容易埋雷——我就在生产环境里见过一个变量被多线程乱改类型,导致下游报AttributeError,排查了半天。

我的习惯:在函数入口处用 type() 或 isinstance() 做类型断言,尤其是处理文件路径、时间戳、数值时。这样团队里其他人接手时一眼就能看到预期类型。

常用的内置类型就几个:

  • int / float / complex – 数值计算,注意浮点数精度问题(质控里算误差时要小心)。
  • str – 不可变,切片、格式化、正则都离不开。
  • list / tuple – 列表可变,元组不可变。我习惯把从配置文件里读出的固定参数用元组存,防止误改。
  • dict / set – 字典用于键值映射(质控参数表),集合用于去重或交集运算。
  • bool / NoneType – 注意 None 不是 False,is 与 == 有区别。我曾经在判断空列表时用 if list == [],其实用 if not list 更Pythonic。

来,看个例子:

# 变量动态绑定
count = 10
count = 10.5   # 同一变量,类型从 int 变为 float

# 字典用于质控参数
qc_params = {
    "tolerance": 0.01,
    "sample_size": 128,
    "output_format": "json"
}

# 集合去重
errors = [101, 102, 101, 103, 102]
unique_errors = set(errors)
print(unique_errors)  # {101, 102, 103}

3.2 控制流:if / for / while

先说过if。Python里没有switch,但可以用 if-elif-else 链,或者用字典映射。质控工具里经常要根据不同的检测项分发处理函数,我建议用字典+lambda,比一串elif好维护。

常用模式:状态机或策略分发,用字典代替长if链。
def handle_a(data): pass
def handle_b(data): pass

dispatcher = {
    "test_a": lambda d: handle_a(d),
    "test_b": lambda d: handle_b(d),
    "default": lambda d: print("Unknown test")
}

def run_test(test_name, data):
    handler = dispatcher.get(test_name, dispatcher["default"])
    handler(data)

再说for。我个人觉得 for 是Python里最优雅的循环。能不用 while 就尽量不用,因为我曾用while写了一个死循环——那次是忘了更新循环计数器,CPU跑到100%,服务器差点宕掉。用 for ... in 自带终止,安全。

质控场景里经常需要批量处理文件:

import os

reports = []
for fname in os.listdir("/data/qc_results"):
    if fname.endswith(".csv"):
        reports.append(parse_csv(fname))

while 更适合不确定次数的循环,比如等待外部设备状态:

import time

while not device_is_ready():
    time.sleep(1)
    print("Waiting for device...")
循环类型使用场景避坑提示
for … in遍历已知序列不要在循环里修改正在遍历的列表,否则用切片拷贝
while条件满足则继续一定要有终止条件,否则死循环

3.3 函数定义与装饰器

函数定义很简单:def func(param1, param2=default):。但我特别想聊的是 装饰器。你可能觉得装饰器是“高级特性”,但在质控工具里它几乎天天用——比如给每个测试函数自动加入开始/结束日志、计算运行时长、权限校验。

装饰器的本质:接收一个函数作为参数,返回一个新函数。说白了就是“函数外面再包一层”。

import time
import functools

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        elapsed = time.perf_counter() - start
        print(f"[{func.__name__}] 耗时 {elapsed:.3f} 秒")
        return result
    return wrapper

@timer
def run_quality_check(data):
    # 模拟复杂计算
    time.sleep(0.1)
    return len(data)

# 调用
run_quality_check([1,2,3,4,5])
我曾经踩过的坑:忘记了 @functools.wraps,导致被装饰后的函数丢失了原来的 __name__ 和 __doc__。这在单元测试里会出大问题。所以任何时候写装饰器,记得加上 @functools.wraps。

参数化的装饰器更灵活,比如可以传入日志级别:

def log_level(level):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            if level == "DEBUG":
                print(f"DEBUG: 调用 {func.__name__}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

@log_level("DEBUG")
def measure(): pass

3.4 类与继承

关于类,我只需要你记住两个核心点:封装和继承。质控工具里经常需要定义“检测器”基类,然后针对不同检测项派生子类。比如有一个基类 QCChecker,子类实现 check() 方法。

class QCChecker:
    def __init__(self, name):
        self.name = name

    def check(self, data):
        raise NotImplementedError("子类必须实现 check 方法")

class RangeChecker(QCChecker):
    def __init__(self, name, min_val, max_val):
        super().__init__(name)
        self.min_val = min_val
        self.max_val = max_val

    def check(self, data):
        return self.min_val <= data <= self.max_val

# 使用
checker = RangeChecker("温度范围", 20.0, 30.0)
result = checker.check(25.5)
print(f"{checker.name}: {result}")  # True

继承时要注意 super() 的调用顺序。Python用MRO(方法解析顺序)决定父类查找,多继承的时候容易混乱。我的建议是尽量用组合代替多继承,或者用抽象基类(ABC)严格规定接口。

一个小技巧:用 __repr__ 和 __str__ 让打印对象时显示有意义的信息,调试时省很多眼神。

好了,基础部分先复习到这里。你可能会觉得东西有点碎,但没关系,接下来每个实战章节都会反复用到这些语法——你会在具体场景里把它们彻底练熟。

本章知识体系

Python基础回顾——知识结构 变量与数据类型 int / float / complex str (不可变) list / tuple dict / set bool / NoneType 控制流 if-elif-else for … in (遍历) while (条件循环) break / continue 字典分发替代switch 函数与装饰器 def / return 参数:默认/不定长 装饰器:函数包裹 @functools.wraps 参数化装饰器 类与继承 封装:属性+方法 继承:super() / MRO ABC抽象基类 这四块是质控工具开发最常用的基础语法,后续章节会在实战中反复强化。