3、Python基础速通(二):变量、数据类型、运算符——测试数据生成的基石

好,咱们接着聊。上一章我们把Python环境搭好了,也跑通了第一个脚本。这一章,我要带你搞定Python里最核心的三个东西:变量、数据类型、运算符。

你可能会问,这跟嵌入式测试有什么关系?

关系大了去了。你想想看,我们每天要生成多少测试数据?几百组寄存器配置、几千条串口报文、上万次ADC采样值……这些数据怎么来?说白了,就是靠变量存、靠数据类型定义、靠运算符算出来的。

我个人习惯,把这一章叫做「测试数据生成的三板斧」。学完它,你就能自己写脚本批量造数据了。

3.1 变量——给数据贴个标签

变量是什么?很简单,就是给数据起个名字。

比如你测一个温度传感器,采集到的值是25.6℃。你总不能每次都写25.6吧?把它存到变量里,用的时候直接叫名字就行。

temperature = 25.6
print(temperature)  # 输出 25.6

嗯,这里要注意:Python的变量不需要提前声明类型。你直接赋值,它就自动认了。这在快速写测试脚本时特别爽。

我的习惯:变量名一定要见名知意。测什么就用什么命名。比如 adc_valueuart_datagpio_status。别用 a、b、c 这种,回头自己都看不懂。

变量命名有几个硬规矩:

  • 只能包含字母、数字、下划线
  • 不能以数字开头
  • 不能是Python关键字(比如 if、for、while)

还有个小技巧:Python里变量名区分大小写。 Temptemp 是两个不同的变量。我曾经因为这个bug查了半小时……嗯,不说了,都是泪。

3.2 数据类型——数据长什么样

Python的数据类型,说白了就是告诉计算机:你手里拿的是什么东西。

是数字?是文字?是开关状态?还是列表?不同类型,玩法不一样。

3.2.1 数字类型:int 和 float

int 是整数,float 是浮点数(带小数)。

reg_addr = 0x3F  # int,寄存器地址
voltage = 3.3     # float,电压值

我在项目中遇到过一个问题:两个浮点数做比较,明明看起来相等,但 if 判断就是进不去。为什么?因为浮点数有精度误差。后来我改用 round() 或者比较差值范围才搞定。

避坑指南:千万不要直接用 == 比较两个浮点数。用 abs(a - b) < 1e-6 这种方式。

3.2.2 字符串类型:str

字符串就是文本。在测试脚本里,我们经常用它来拼报文、写日志。

uart_cmd = "AT+START\r\n"
log_msg = 'ADC value: ' + str(adc_value)

字符串可以用单引号,也可以用双引号。我个人习惯用双引号,因为有时候字符串里会包含单引号(比如 don't)。

字符串拼接有几种方式:

  • + 拼接:简单直接
  • f-string:Python 3.6+ 推荐,超好用
# f-string 示例
channel = 3
expected = f"CH{channel}: 1200mV"
print(expected)  # 输出 CH3: 1200mV

你看,用 f-string 拼测试报文,是不是比用 + 清爽多了?

3.2.3 布尔类型:bool

布尔值只有两个:True 和 False。在测试脚本里,它常用来表示测试结果。

test_passed = True
if test_passed:
    print("测试通过")
else:
    print("测试失败")

布尔值其实可以当成数字用:True 是 1,False 是 0。但我不建议这么干,代码可读性会变差。

3.2.4 列表和元组

列表(list)和元组(tuple)都是用来存一堆数据的。区别在于:列表可以改,元组不能改。

# 列表:测试用例集合
test_cases = ["case1", "case2", "case3"]
test_cases.append("case4")  # 可以添加

# 元组:固定参数集合
gpio_pins = (1, 3, 5, 7)  # 不能修改

我建议:如果数据后续会变,用列表;如果数据是固定的(比如硬件引脚号),用元组。这样代码更安全,别人一看就知道你的意图。

3.2.5 字典:键值对

字典(dict)是测试脚本里的神器。它用键(key)来存值(value),查找速度飞快。

# 寄存器配置表
reg_config = {
    "POWER_CTRL": 0x01,
    "CLOCK_DIV":  0x04,
    "INT_ENABLE": 0x08
}

# 按名字取值
print(reg_config["POWER_CTRL"])  # 输出 1

我在做自动化测试时,经常用字典来存设备的配置参数。比用列表一个个索引方便多了。

3.3 运算符——让数据动起来

有了变量和数据类型,接下来就是怎么操作它们了。运算符就是干这个的。

3.3.1 算术运算符

加减乘除,跟数学一样。但有几个要注意的:

运算符 说明 示例
+ 5 + 3 = 8
- 5 - 3 = 2
* 5 * 3 = 15
/ 除(结果是浮点数) 5 / 2 = 2.5
// 整除(取整数部分) 5 // 2 = 2
% 取余 5 % 2 = 1
** 幂运算 2 ** 3 = 8

在嵌入式测试里,//% 特别常用。比如你要把毫秒转成秒和毫秒:

total_ms = 1500
seconds = total_ms // 1000  # 1
ms = total_ms % 1000        # 500

3.3.2 比较运算符

比较运算符返回布尔值。在测试脚本里,它用来判断结果对不对。

actual = 1200
expected = 1200
if actual == expected:
    print("测试通过")
else:
    print(f"失败:期望{expected},实际{actual}")

常用的比较运算符:==!=><>=<=

重要提醒:一个等号 = 是赋值,两个等号 == 才是比较。我见过太多新手在这上面栽跟头了。

3.3.3 逻辑运算符

逻辑运算符用来组合多个条件:

  • and:两个条件都成立
  • or:至少一个条件成立
  • not:取反
voltage = 3.3
current = 0.5
if voltage > 3.0 and current < 1.0:
    print("设备工作正常")

我曾经写过一个测试脚本,用 andor 组合了五六个条件,结果把自己绕晕了。后来我学乖了:条件太多就拆成几个变量,用有意义的变量名,代码立马清晰了。

3.3.4 成员运算符

这个在测试数据生成里特别实用。in 用来检查某个值在不在列表或字典里。

valid_channels = [1, 2, 3, 4]
ch = 5
if ch in valid_channels:
    print("通道有效")
else:
    print("通道无效,请重新选择")

你看,用 in 是不是比写一堆 == 判断简洁多了?

3.4 实战:生成一组测试数据

好了,理论讲完了。咱们来点实际的。

假设你要测试一个温度传感器,需要生成10组测试数据:温度值从 -20℃ 到 60℃,步进 10℃。每组数据包括:序号、温度值、对应的ADC码值(假设每℃对应 10 个码)。

# 生成温度测试数据
test_data = []
for i in range(10):
    temp = -20 + i * 10
    adc_code = temp * 10
    test_data.append({
        "序号": i + 1,
        "温度": temp,
        "ADC码值": adc_code
    })

# 打印结果
for item in test_data:
    print(f"第{item['序号']}组:温度={item['温度']}℃, ADC={item['ADC码值']}")

输出结果:

第1组:温度=-20℃, ADC=-200
第2组:温度=-10℃, ADC=-100
...
第10组:温度=60℃, ADC=600

你看,不到10行代码,10组测试数据就生成了。这就是Python的效率。

我的建议:在实际项目中,把这种数据生成逻辑封装成函数。下次换个传感器,改几个参数就能复用。别每次都从头写。

3.5 本章小结

这一章我们聊了:

  • 变量:给数据起名字,方便调用
  • 数据类型:int、float、str、bool、list、tuple、dict——每种类型都有它的用武之地
  • 运算符:算术、比较、逻辑、成员——让数据按照你的意愿变化

这些东西,说白了就是Python的「砖块」。下一章,我们要用这些砖块搭房子了——流程控制。到时候,你的脚本就能根据不同的条件做不同的事情,那才是真正的自动化。

嗯,今天就到这儿。把上面的代码敲一遍,感受一下。有问题随时翻回来看看。