《嵌入式AI筑基笔记01:Python语法,一个C视角的翻译》
前言
写了十几年的 C 语言,天天跟内存、指针、寄存器打交道,我早已习惯了“没有轮子自己造”的生活。
- • 要复杂功能?没问题,我上 Linux,内核自己裁剪。
- • 成本要压?再难也得想办法——因为这就是嵌入式工程师的日常。
我们这行,最不怕的就是困难。因为困难本身就是工作的一部分。
学习的本质是让新知识与我们已有的知识建立联系,最后融入到我们的知识体系,内化成我们的知识。 这就需要我们带着主动的学习态度去研究,不断提出问题,思考问题,最后解决问题。
毕竟学了十几年 C,脑子里早已有一套固定的“知识体系”。我现在要做的是想办法将新知识挂上去。所以开始学 Python 之前,我给自己列了个问题清单:
- • 都说 Python 简洁,简洁在哪? 跟 C 比,跟 C++ 比?
- • 有什么“特殊的地方”要注意? 关键字、运算符、数据类型、操作方法……
带着这些问题,我开始了 Python 的第一课。
学了一段时间,不得不说:Python 确实简洁。能写一行的,绝不写两行;能省掉的符号,一个不留。对于我这种强迫症,这点很舒服。但新的问题又冒出来了:内存谁管?效率谁保证? 好像……没人在乎?大家只关心“能不能跑”,“跑得快不快”是编译器的事。也许这就是两种思维方式的差异:我们习惯了自己把控一切,而 Python 的世界里,很多事仿佛交给“环境”就行了。
以下让我们带着问题正式开始 Python 语言的学习,一步步揭开它的神秘面纱。
注:每一条语法,我都尽量用 C 程序员的视角看一眼——“这个和 C 一样”,“这个和 C 不一样”,“这个比 C 方便”,“这个得小心”。
注释

行注释,使用 # 号段注释,使用 ''' ''' 或 """ """
# 行注释,使用 #print('hello') # 打印 'hello' 字符串 hello# 段注释,使用 ''''''或""" """'''多行注释 1多行注释 2'''""" 多行注释 3多行注释 4"""
C 程序员的视角:
- • 行注释:Python 用
#,C 语言用 // - • 块注释:Python 用
''' 或 """,C 语言用 /* */
注意:Python 的块注释其实是“没被赋值的字符串”,不是真正的注释语法,但用起来效果一样。
行结束
• 多条语句在同一行时,用 ; 隔开,不推荐这种写法# 行结束不用 ;print(123) # 123print("word") # word# 多条语句在同一行时,用 ; 隔开,不推荐这种写法print(100);print("word") # 不推荐 100\n word
C 程序员的视角:
- • 语句结束:Python 换行即可,C 语言必须用
;
注意:别贪图“一行多语句”,Python 的哲学是“可读性优先”。
输入输出
# 输入类型默认为 strings = input("input:") # input:5print(s, type(s)) # 5 <class 'str'># 通过强转获得其它类型数据n = int(input("input:")) # input:21print(n, type(n)) # 21 <class 'int'>f = float(input("input:")) # input:3.14print(f, type(f)) # 3.14 <class 'float'>
C 程序员的视角:
- • 输入函数:Python 用
input(),C 语言用 scanf() - • 类型处理:Python 默认字符串需强转,C 语言用格式控制符指定类型
注意:C 的 scanf 用 %d、%f 指定类型,Python 用 int()、float() 事后转换。
输出 print
原型:print(self, *args, sep=' ', end='\n', file=None)
示例:
- • 打印多个内容,空格连接:
print(内容1,内容2) - • 打印多个内容,指定符号连接:
print(内容1, 内容2,sep='符号') - • 打印内容,在结尾加上指定符号:
print(内容, end='符号')
# 分隔符 sep, 默认为 ' ' 空格# 结束符 end, 默认为 '\n' 换行符print() # 打印空行 \nprint("hello") # 打印文本 hellotmp = 100print(tmp) # 打印变量的值 100print("feng", 100) # 打印多个内容,默认空格隔开 feng 100print("feng", 100, sep="---") # 打印多个内容,使用'---'分割 feng---100print("feng", end="==") # 打印内容,结尾加上'==' feng==
C 程序员的视角:
- • 输出函数:Python 用
print(),C 语言用 printf() - • 分隔符控制:Python 用
sep 参数,C 语言需手动加空格 - • 结尾控制:Python 用
end 参数,C 语言需手动控制 \n
注意:默认会换行,不想换行要指定 end=''。
占位符
% 占位符(类C风格)

# % 占位符# %s 字符串 %d 整数 %f 浮点数name = "feng"age = 20score = 99.55# 默认保留 6 位小数, 我是feng,今年20岁,得了99.550000分print("我是%s,今年%d岁,得了%f分" %(name, age, score))# 指定保留 1 位小数,我是feng,今年20岁,得了99.550000分print("我是%s,今年%d岁,得了%.1f分" %(name, age, score))
C 程序员的视角:
- • 占位符语法:Python 用
% 格式化,C 语言用 printf 的 %
注意:%d、%f、%s 与 C 语言一样。
{} 占位符 .format(Python 风格)
• 基础用法:print("{},{}".format(参数1, 参数2))• 带编号的用法:print("{0},{1}{0}".format(参数1, 参数2))• 带名字的用法:print("{参数1名},{参数2名}".format(参数1=值, 参数2=值))• 小数精度控制:print("{:.nf}".format(参数))# {}占位符.formatname = "feng"age = 20score = 99.55# 基础用法,参数顺序填入前面占位 我是feng,今年20岁print("我是{},今年{}岁".format(name, age))# 带编号用法,可重复使用,依据编号填入前面占位 我是feng,今年20岁,他们叫我fengprint("我是{0},今年{1}岁,他们叫我{0}".format(name, age))# 带名字用法,依据名字填入前面占位 我是seven,今年18岁,他们叫我sevenprint("我是{name},今年{age}岁,他们叫我{name}".format(name="seven", age=18))# 精确小数位 1 位 分数99.5print("分数{:.1f}".format(score))
C 程序员的视角:
- • 占位符:Python 用
{},C 语言无对应 - • 参数顺序:Python 可按顺序或编号,C 语言必须按顺序
注意:编号和名字可以重复用,不用像 C 那样传好几遍。
f-string(Python 3.6+,最推荐)
• 基础用法:print(f'{参数1}{参数2}')• 直接做运算:print(f'{参数1+参数2}')• 精确小数位:print(f'{参数:.1f}')- • 显示百分号:
print(f'{参数:.0%}')
# f-stringname = "feng"age = 20score = 99.55# 基础用法 我是feng,今年20岁print(f'我是{name},今年{age}岁')# 直接做运算 20 + 1 = 21print(f'{age} + 1 = {age + 1}')# 精确小数位 1 位 分数99.5print(f'分数{score:.1f}')# 控制宽度和对齐,占6个字符宽度print(f"姓名:{name:>6}") # 右对齐 姓名: fengprint(f"姓名:{name:<6}") # 左对齐 姓名:fengprint(f"姓名:{name:^6}") # 居中对齐 姓名: feng# 千位分隔符(处理大数字很有用)number = 1234567890print(f"{number:,}") # 1,234,567,890# 显示百分号num = 0.85print(f"正确率:{num:.%}") # 正确率:85.0%print(f"正确率:{num:.0%}") # 正确率:85%
C 程序员的视角:
- • 变量嵌入:Python 可直接
{变量名},C 语言无对应 - • 表达式:Python 可直接
{age+1},C 语言无对应
注意:这是最推荐的写法
变量
• Python 是弱类型语言,不需要声明变量类型# 定义,python 是弱类型语言,不需要声明变量类型a = 10str = "3.5"print(type(a), type(str)) # <class 'int'> <class 'str'># 支持多变量一起定义a, b = 10, 3.3print(a, type(a), b, type(b)) # 10 <class 'int'> 3.3 <class 'float'>m, n = 12, "hello"print(m, type(m), n, type(n)) # 12 <class 'int'> hello <class 'str'>
C 程序员的视角:
- • 变量声明:Python 不需要,C 语言必须
int a; - • 类型检查:Python 运行时确定,C 语言编译时确定
注意:Python 是“看值定类型”,你赋什么值,它就是什么类型。变量定义不用写 int、char 了,直接 a=10 就行。支持多变量同时赋值。
获取变量类型
# 获取变量类型 type()val = 10print(val, type(val)) # 10 <class 'int'>
C 程序员的视角:
- • 查看类型:Python 用
type(),C 语言用 sizeof() 只能看大小,不能看类型
注意:C 里你没法在运行时问“这个变量是什么类型”,Python 可以。
类型转换
# 强转数据为整型f = 10.5s = "12"print(int(f), int(s)) # 强转为整型 10 12# 强转为浮点数m = 5s = "5.67"print(float(m), float(s)) # 强转为浮点数 5.0 5.67# 强转为字符串f = 3.14print(str(f), type(str(f))) # 强转为字符串 3.14 <class 'str'>
C 程序员的视角:
- • 类型转换:Python 用
int()、float() 等函数,C 语言用隐式转换或强制 (int)
注意:强转与 C 语言类同,C 语言没有字符串转换函数,int("12") 可以把字符串转数字,但如果字符串是 "12.5" 会报错,得先转 float。
命名
• 与 C 语言一致,支持数字、字母、下划线,不能数字开头• 命名可保留现在习惯,全小写用 _ 分割,如 my_teacher# 变量命名# 与C语言一致,支持数字、字母、下划线,不能数字开头d = 12_x = 3.12x12 = 5.65print(d, _x, x12) # 12 3.12 5.65# 区分大小写str = "hello"Str = "feng"print(str, Str) # hello feng# 中文也可以,但是不建议你好 = 3print(你好, type(你好)) # 3 <class 'int'># 命名可保留现在习惯,全小写用_分割,如my_teacher
删除
# 删除变量 dela = 10print(a) # 10del aprint(a) # 报错 NameError: name 'a' is not defined
关键字
# 关键字# 获取所有关键字''' ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']"'''import keywordprint(keyword.kwlist) # 获取所有关键字
关键字列表:['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
交换两数的值
# 交换两数的值a, b = 10, 12a, b = b, a # 这写法比 C 语言简单多了print(a, b) # 12 10
C 程序员的视角:
- • 交换变量:Python 用
a, b = b, a,C 语言需要临时变量 t = a; a = b; b = t;
注意:我看到这,沉默了......
运算符
算术运算符

# 算术运算符# + - * / 加减乘除a, b = 10, 0.5print(a+b, a-b, a*b, a/b) # 10.5 9.5 5.0 20.0# % 取余m = 12print(m%5, m%6) # 2 0# // 向下取整num = 5print(num//2, num//3) # 2 1# ** 次方,幂n,m = 2, 3print(n**m, m**n) # 2^3 3^2 8 9# e 科学计数法a, b = 3.14*10**3, 3.14e3print(a, b) # 3140.0 3140.0
C 程序员的视角:
- • 加减乘除:Python 用
+ - * /,C 语言相同 - • 向下取整除法:Python 用
//,C 语言无对应,/ 对整数是截断 - • 次方:Python 用
**,C 语言用 pow() 函数
注意:// 是“向下取整”,不是“向零取整”。
- • 在 Python 里:
-5//2 = -3(向下取整)
赋值运算符
复合运算符
# 复合运算符 += 、-= 、*=、/=a = 10a += 2print(a) # 12a -= 2print(a) # 10a *= 2print(a) # 20a /= 2print(a) # 10.0
比较运算符

# 比较运算符 >、>=、 <、 <=、==、!=# 比较结果为 bool 变量a, b = 10, 4 # True True False False False Trueprint(a>b, a>=b, a<b, a<=b, a==b, a!=b)
成员运算符

# 成员运算符# in 是成员,not in 不是成员print(2 in [1, 2, 5]) # in 是成员 Trueprint(3 not in [1, 3, 5]) # not in 不是成员 False
身份运算符

# 身份运算符a = [100, 101]b = a # 赋值,实际b得到的是a地址c = a.copy() # 拷贝一份a,c与a地址并不一样# 打印a,b,c地址 a:2594599232008, b:2594599232008, c:2594599232072print(f'a:{id(a)}, b:{id(b)}, c:{id(c)}')print(a is b, a is not b) # True Falseprint(a is c, a is not c) # False True
C 程序员的视角:
- • 比较内存地址:Python 用
is,C 语言用 == 比较指针值或 memcmp() - • 取地址:Python 用
id(),C 语言用 &
注意:C 语言“值”和“地址”是分开的。is 本质上比较的就是指针。
逻辑运算符

- • bool 类型:False 为假,True 为真• tuple 元组:空元组 () 为假,其他为真
# 逻辑运算符# and、or、not 与或非print(not True, not False) # False Trueprint(True or False, True or True) # True Trueprint(True and False, True and True) # False True# 隐藏的 bool 规则print(bool(0), bool(23)) # 数字类型: 0是假,其他为真 False Trueprint(bool(''), bool('23')) # 字符串类型: 空字符串''为假,其他为真 False Trueprint(bool(None)) # NoneType类型: None是假 Falseprint(bool([]), bool([2,3])) # list类型:空列表[]是假,其他为真 False Trueprint(bool(()), bool((2,3))) # tuple元组: 空元组()为假,其他为真 False Trueprint(bool({}), bool({"s":1})) # dict字典:空字典{}为假,其他为真 False True
C 程序员的视角:
- • 逻辑运算符:Python 用
and or not,C 语言用 && || ! - • 假值规则:Python 中
False、0、''、[]、()、{}、None 都是假,C 语言只有 0/NULL 是假
注意:C 语言里“假”只有 0(NULL);Python 里“空”的东西都是假。
运算符优先级

注意事项

总结
学了这几天 Python,我给自己列了几条“从 C 过来要记住的事”:
1. 没有 ++、--C 语言有 ++、--,Python 要用 += 1、-= 1
2. 没有 ? : 三目C 语言有 ? :,Python 要用 a if cond else b
3. 缩进决定代码块C 语言用 {} 决定代码块,Python 用缩进,别混用空格和 Tab
4. 变量不用声明类型C 语言必须声明类型,Python 靠赋值确定类型
5. // 是向下取整C 语言的 / 是向零取整,负数除法要注意
6. and or notC 语言用 && || !,符号变了
7. 空的东西都是假C 语言只有 0 和 NULL 是假,Python 中 ''、[]、None 都是假
这是 Python 学习的第一篇,也是最基础的一篇——语法规则。
学完这一课,我的三个感受:
- 1. 熟悉的地方:运算符、大部分语法结构,可以直接平移
- 2. 陌生的地方:类型系统、代码块组织、假值规则,得重新适应
- 3. 惊喜的地方:交换变量、f-string、多变量赋值
接下来学什么
这只是 Python 学习的“开胃菜”。按照计划,后面还有:
第一篇:语法规则(与 C 的对比) ✅ 已完成第二篇:数据结构:列表、元组、字典、集合 ⏳ 准备中第三篇:流程控制:条件、循环、推导式 ⏳第四篇:函数与模块:定义、参数、作用域 ⏳第五篇:对象和类:Class ⏳第六篇:文件操作与异常处理 ⏳第七篇:NumPy 入门:像操作内存一样操作数据 ⏳第八篇:Pandas 基础:给数据“做表格” ⏳
一步一步来,不急。