Py学习  »  Python

Python 基础语法(一):常量、变量、输入输出与运算符

码上编程学习社 • 昨天 • 24 次点击  

一、前言:为什么用 C++ 的视角学 Python

很多同学是先从 C / C++ 入门,再来学 Python 的。这两门语言的设计哲学差异非常大:
  • C++
     强调性能与控制,变量的类型在编译期就固定死了,编译器替你"把关",写错了直接编译报错。
  • Python
     强调简洁与开发效率,变量的类型在运行时才确定,怎么写都行,写错了运行时报错。
正因为差异大,学 Python 最忌讳"照着 C++ 的思维硬套"。这篇文章把课程笔记里每一个知识点都和 C++ 做对比,哪里有区别,就同时给出 Python 和 C++ 两段代码,让你"边找不同边记语法"。对于课程里一句带过的内容(位运算、身份运算符、成员运算符等),我也做了补充,保证覆盖全面。
先看一张总览对比表,后面再逐个展开:

二、常量和表达式

2.1 什么是"表达式"

在编程里,1 + 2 - 3 这种算式称为表达式,算出来的结果叫表达式的返回值;其中 12 3 这种直接写出来的数据叫字面值常量+ - * / 这种符号叫运算符(操作符)。
Python 可以直接把解释器当计算器用:
print(1 + 2 - 3)      # 0print(1 + 2 * 3)      # 7  先乘除后加减print((1 + 2) * 3)    # 9  括号改变优先级
注意:Python 里运算符和数字之间有没有空格、有几个空格都无所谓(1+2 和 1 + 2 等价),但为了美观,习惯上写一个空格。

2.2 关键差异:除法 /

这一条 C 系选手最容易踩坑。在 C++ 里,两个整数相除,小数部分直接截断在 Python 里,/ 永远返回浮点数,更符合日常直觉。
# Pythonprint(1 / 2)      # 0.5  不会截断成 0print(5 / 2)      # 2.5print(10 / 4)     # 2.5
// C++


    
int a = 1, b = 2;std::cout << a / b << std::endl;   // 0   整数除法,小数截断std::cout <5.0 / 2 << std::endl; // 2.5 只要有一边是浮点数,结果就是浮点数
记忆口诀:Python 的 / 永远做"真除法";C++ 的 / 只有在两边都是整数时才做"整数除法"。

2.3 示例:求平均值

# Python:四个分数求平均print((67.5 + 89.0 + 12.9 + 32.2) / 4)   # 50.400000000000006
(为什么会多个小尾巴?这就是后面 6.2.2 节要讲的浮点数精度问题,先留个印象。)
// C++:同样的逻辑double avg = (67.5 + 89.0 + 12.9 + 32.2) / 4;std::cout << avg << std::endl;            // 50.4

三、变量和类 

3.1 变量是什么

计算稍微复杂一点时,需要把中间结果保存下来,这就用到了变量。比如求四个分数的方差,得先算出平均值 avg 存起来:
avg = (67.5 + 89.0 + 12.9 + 32.2) / 4total = (67.5 - avg) ** 2 + (89.0 - avg) ** 2 + (12.9 - avg) ** 2 + (32.2 - avg) ** 2result = total / 3print(result)
可以把变量理解成内存里的一块空间(就像宿舍楼里的房间),每个房间有名字、能存数据。avgtotalresult 就是三个变量。

3.2 定义变量:类型声明是最大区别

Python 定义变量极其简单,不需要写类型

a = 10           # 不用写 int,解释器自己知道是整数name = 'Tom'     # 不用写 string
C++ 必须先声明类型:
int a = 10;              // 必须写 intstd::string name = "Tom"// 必须写 std::string
为什么? C++ 要在编译期就知道变量占几个字节、能做什么操作;Python 是解释执行的,运行时看到赋了什么值再"猜"类型,所以可以省掉类型声明。

3.3 变量命名规则

两门语言的硬性规则基本一致:

  • 变量名由数字、字母、下划线构成
  • 数字不能开头
  • 不能和关键字重复
  • 大小写敏感
    num 和 Num 是两个变量)
软性规范也相通:名字要"见名知义",多个单词组合起来( totalCountpersonInfo)。
补充小知识:Python 官方规范 PEP 8 更推荐用 snake_case(全小写 + 下划线,如 total_count),而 C++ 习惯用驼峰(totalCount)。课程里示例用驼峰也没问题,但面试或写正式项目时,Python 风格请尽量用下划线命名。

3.4 使用变量:读取与修改

a = 10print(a)      # 读取:10a = 20        # 修改:直接再赋一次值print(a)      # 20
注意:Python 里定义变量和修改变量用的都是 =,语法上没区别,这点和 C++ 一样。也支持用一个变量给另一个变量赋值:
a = 10b = aprint(b)      # 10
注意:Python 里定义变量和修改变量用的都是 =,语法上没区别,这点和 C++ 一样。也支持用一个变量给另一个变量赋值:
a = 10b = aprint(b)      # 10

3.5 数据类型对比

Python 内置的几种基本类型:

# Python:用 type() 查看类型a = 10print(type(a))      


    
# a = 0.5print(type(a))      # a = 'hello'print(type(a))      # a = Trueprint(type(a))      # 
// C++:类型写在声明里,编译器会校验int a = 10;                  // 4 字节,范围约 -21 亿 ~ 21 亿float f = 0.5f;              // 单精度,约 4 字节double d = 0.5;              // 双精度,约 8 字节bool flag = true;            // 小写 true/false

3.5.1 重点差异一:Python 的 int 没有上限

C++ 的 int 一般占 4 字节,最大值约 21.47 亿,超出就溢出(甚至属于未定义行为):

// C++:int 溢出int a = 2147483647;a = a + 1;          // 溢出,结果变成 -2147483648(未定义行为)
Python 的 int 只要内存够,想多大就多大:
# Python:任意大整数print(10 ** 30)     # 1000000000000000000000000000000,照算不误

3.5.2 重点差异二:Python 没有单独的"字符类型"

C++ 里有 char,一个字符占一字节;Python 里 'a' 和 "hello" 都是 str,没有单字符类型。而且 Python 的单引号和双引号完全等价,'hello'  和 "hello" 没有任何区别。字符串拼接用 +
a = 'hello'b = 'world'print(a + b)          # helloworldprint(len(a))         # 5
// C++std::string a = "hello";std::string b = "world";std::cout << a + b << std::endl;   // helloworldstd::cout << a.size() << std::endl; // 5
注意:两门语言里字符串都不能直接和整数相加。Python 的 'a' + 10 会直接抛 TypeError;C++ 的 std::string + 整数 则是编译报错(没有对应的 operator+ 重载)。C++ 里 std::string 可以 +  单个字符(s + 'a' 合法),这算是小差异。

3.6 动态类型 vs 静态类型

这是 Python 和 C++ 最本质的区别之一。
Python 是动态类型:一个变量的类型在程序运行过程中可以改变。
a = 10print(type(a))      # a = 'hello'print(type(a))      #   ← 类型变了!合法
C++ 是静态类型:变量一旦定义,类型就固定了,再赋别的类型直接编译报错。
int a = 10;a = "hello";        // 编译错误:不能把 const char* 赋给 int
动态类型是一把双刃剑:
  • 优点:中小型程序写起来快,一段代码能同时处理多种类型(比如一个函数既能传整数又能传字符串)。
  • 缺点:大型项目里,A 同事写的代码 B 同事看不懂到底传进来什么类型,协作成本高。所以很多大型 Python 项目后来都引入了"类型注解"(type hints)。

3.7 类型转换

Python 用内置函数转类型:int()float()str() bool()
s = "10"num = int(s)        # 字符串 → 整数,num = 10f = float("3.14")   # 字符串 → 浮点数t = str(123)        # 整数 → 字符串 "123"
C++ 用强制类型转换或流方式:
std::string s = "10";int num = std::stoi(s);       // C++11,字符串 → 整数int num2 = static_cast<int>(3.99);   // 浮点 → 整数,结果是 3(截断)
注意 int("3.14") 在 Python 里会报错(无法直接转换带小数点的字符串),要先用 float()。C++ 的 static_cast(3.99) 则是直接截断小数位。

四、注释

注释不会被程序执行,只是给人看的,帮自己和别人理解代码。两门语言的单行注释符号不同:
# Python:井号注释# 计算四个数字的方差avg = 10
// C++:双斜杠注释// 计算四个数字的方差int avg = 10;
多行注释 / 文档注释:
# Python:三引号(文档字符串,也可以当作多行注释)"""这里是多行说明可以写很多行"""
/* C++:块注释   这里是多行说明   可以写很多行 */
补充两条写注释的规范(两门语言通用):
  1. 内容要准确
    :注释必须和代码一致,代码改了注释要同步改。
  2. 篇幅要合理
    :既不能不写,也不要长篇大论;中文团队一般要求用中文写。

五、输入输出

5.1 输出:print vs std::cout

Python 用 print() 输出,可以一次打印多个值,默认用空格分隔

print(123)          # 1 2 3print('hello')          # hellonum = 10print(num)              # 10
C++ 用流输出,每个值之间要靠 << 手动连接,分隔符也要自己写:
std::cout <1 1 2 3
Python 的 print 还支持自定义分隔符和结尾:
print(123, sep='-')      # 1-2-3print(123, sep='-', end='!\n')   # 1-2-3!
对应记忆print(a, b) ≈ C++ 的 std::cout << a << " " << b;

5.2 格式化输出:f-string vs C++

Python 最常用的是 f-string,在字符串前加 f,用  {} 内嵌变量或表达式:

num = 10print(f'num = {num}')        # num = 10print(f'3 的平方是 {3 ** 2}')  # 3 的平方是 9
C++ 对应写法(printf 或流):
int num = 10;printf("num = %d\n", num);              // C 风格std::cout  << num << std::endl;  // C++ 流风格

5.3 输入:input vs std::cin

这是新手最常踩的坑:Python 的 input() 返回的一定是字符串,想做算术运算必须先转类型!

num = input('请输入一个整数: ')   # 用户输入 10,num 是字符串 "10"print(f'你输入的是 {num}')
# 下面这样是错的:字符串拼接,不是加法a = input('请输入第一个整数: ')b = input('请输入第二个整数: ')print(f'a + b = {a + b}')          # 输入 3 和 4,结果是 "34" 不是 7
# 正确写法:先转换类型a = int(input('请输入第一个整数: '))b = int(input('请输入第二个整数: '))print(f'a + b = {a + b}')          # 7
C++ 的 std::cin 会根据变量的类型自动转换,不需要手动转:
int num;std::cin >> num;              // 直接读成 int,无需转换int a, b;std::cin >> a >> b;           // 一次读两个,空格/回车分隔std::cout  << a + b << std::endl;   // 7
总结差异:C++ 的 cin >> 是"喂给类型化变量",读进来就是那个类型;binpt() 永远给字符串,一切类型转换都得自己动手。这也体现了 Python "少魔法、多显式"的设计。

5.4 综合示例:输入 4 个小数求平均值

a = float(input('请输入第一个数字: '))b = float(input('请输入第二个数字: '))c = float(input('请输入第三个数字: '))d = float(input('请输入第四个数字: '))avg = (a + b + c + d) / 4print(f'平均值: {avg}')
#include int main() {    double a, b, c, d;    std::cin >> a >> b >> c >> d;    double avg = (a + b + c + d) / 4;    std::cout  << avg << std::endl;    return 0;}

六、运算符

6.1 算术运算符

两门语言共有的:+ - * / %(取余)。Python 独有:**(乘方)和 //(整除)。

乘方对比:
# Pythonprint(4 ** 2)       # 16print(4 ** 0.5)     # 2.0  还能算小数次方
// C++#include std::cout << std::pow(42) << std::endl;    // 16


    
std::cout << std::sqrt(4) << std::endl;      // 2  开方
整除 // 的"向下取整"到底是什么意思?
// 是地板除(floor division),结果是往负无穷方向取整,而不是往零取整。这和 C++ 的整数除法(往零截断)在负数场景下结果完全不同,是高频考点:
# Pythonprint(7 // 2)      # 3print(-7 // 2)     # -4   注意!不是 -3
// C++:整数除法向零截断int x = -7 / 2;    // x = -3   (不是 -4!)
为什么不一样? -7 / 2 的数学结果是 -3.5Python 的 // 向负无穷取整 → -4;C++ 的整数除法向零取整 →  -3。 同理,取余 % 的负数结果也两套逻辑
# Python:结果符号跟随除数print(-7 % 2)     # 1    因为 -7 = 2 * (-4) + 1print(7 % -2)     # -1
// C++:结果符号跟随被除数std::cout  % 2 << std::endl;   // -1   因为 -7 = 2 * (-3) - 1
两门语言都满足恒等式 a == (a // b) * b + (a % b),只是对"整除"的定义不同。记住 Python 的结果永远非负(当除数为正时)即可
除数为 0 的报错机制:两门语言都不允许除 0。
print(10 / 0)   # ZeroDivisionError: division by zero
int x = 10 / 0;  // 运行时崩溃 / 未定义行为

6.2 关系运算符

< <= > >= == !=,两门语言写法完全一样,返回布尔值。

a, b = 10, 20print(a < b)      # Trueprint(a == b)     # Falseprint(a != b)     # True
int a = 10, b = 20;std::cout << (a < b) << std::endl;     // 1(C++ 的 bool 打印为 0/1)std::cout << (a == b) << std::endl;    // 0

6.2.1 字符串可以比较大小(字典序)

Python 直接支持字符串比较,规则是字典序(按字符的编码逐个比较,和查英语词典一个道理):

print('hello' == 'world')   # Falseprint('abc' 'abd')        # True  前两个字符相同,第 3 个 c < d
C++ 的 std::string 也支持 == 和 <;但 C 风格的 char[] 必须用 strcmp
#include std::string s1 = "hello", s2 = "world";std::cout << (s1 == s2) << std::endl;   // 0
// C 风格字符串:不能直接 ==(比的是地址),要 strcmpchar c1[] = "abc";char c2[] = "abd";int r = strcmp(c1, c2);   // 负/0/正,对应小于/等于/大于
易错点:C 语言里 char s1[] = "abc"; char s2[] = "abc"; s1 == s2 比的是地址而不是内容,永远是 false很多 C 系出身的同学在 Python 里一对比就懵,其实 Python 和 C++ 的  std::string 的 == 都是按内容比较的。

6.2.2 浮点数比较:千万不要用 ==(重点)

浮点数在计算机里是近似存储的(IEEE 754 标准),运算会产生极小的误差:

print(0.1 + 0.2)             # 0.30000000000000004print(0.1 + 0.2 == 0.3)      # False  ← 坑!数学上明明相等
C++ 一样:
double a = 0.1 + 0.2;double b = 0.3;std::cout << (a == b) << std::endl;   // 0(false)
正确做法:比较差值是否在误差范围内,而不是严格相等。
# Pythona = 0.1 + 0.2b = 0.3print(abs(a - b) 1e-9)              # Trueprint(-0.000001 < (a - b) 0.000001) # True   ← 注意:Python 支持连续比较!
// C++#include double a = 0.1 + 0.2, b = 0.3;std::cout << (std::abs(a - b) 1e-9) << std::endl;   // 1(true)

6.2.3 Python 独有的"连续比较"

Python 可以直接写 a < b < c,一次比较三个数,相当于"夹在中间"的判断:

a, b, c = 102030print(a < b < c)     # True
C++ 不支持 这种写法,必须拆开用 && 连接:
int a = 10, b = 20, c = 30;std::cout << (a < b && b < c) << std::endl;   // 1

6.3 逻辑运算符(重点)

6.3.1 写法对比

# Pythona, b, c = 102030print(a < b and b < c)     # Trueprint(a < b and b > c)     # Falseprint(a > b or b > c)      # Falseprint(not a < b)           # False
// C++int a = 10, b = 20, c = 30;std::cout << (a < b && b < c) << std::endl;   // 1std::cout << (a < b && b > c) << std::endl;   // 0std::cout << (a > b || b > c) << std::endl;   // 0std::cout << (!(a < b)) << std::endl;         // 0

6.3.2 短路求值(重点)

两门语言都遵循短路求值规则:
  • and
     / &&:左侧为假,结果必假,右侧不再执行
  • or
     / ||:左侧为真,结果必真,右侧不再执行
最经典的验证方法:让右侧写一个除以 0,如果被短路了就不会报错。
# Python:右侧 10/0 永远不会执行,所以不报错print(4 > 7 and 10 / 0 == 1)    # False(10/0 没被求值)print(4 7 or 10 / 0


    
 == 1)     # True(10/0 没被求值)
// C++:同理,右侧被短路bool r1 = (4 > 7) && (10 / 0 == 1);   // false,不会触发除零bool r2 = (4 7) || (10 / 0 == 1);   // true,不会触发除零
短路求值非常实用,常用于先判断、再取值,比如 if x is not None and x > 0:,保证不会因为 x 为空而报错。

6.3.3 深度差异:and / or 返回的是操作数,不是布尔值!

这是 Python 和 C++ 一个非常隐蔽、又很重要的区别。

  • C++ 的 && / || 结果永远是 booltrue/false)。
  • Python 的 and / or 返回的是某个参与运算的对象本身
    • a and b
      a 为假返回 aa 为真返回 b
    • a or b
      a 为真返回 aa 为假返回 b



    
print(0 and 5)      # 0       0 是假,返回 0print(3 and 5)      # 5       3 是真,返回 5print(0 or 5)       # 5       0 是假,返回 5print('a' or 'b')   # 'a'     'a' 非空即真,返回 'a'
这个特性经常被用来写"默认值":
name = input('请输入姓名: 'or '匿名用户'print(f'你好,{name}')   # 用户没输入,就显示"匿名用户"

6.3.4 深度差异:Python 里的"真值"概念

C++ 里 && || ! 严格要求 bool 操作数(其它类型要自己转);

Python 里任何对象都可以直接当布尔用,有一套"真值判定"规则:

  • 判定为的常见对象:00.0''(空字符串)、[](空列表)、None
  • 其余基本都判定为
if '':        # 空字符串 → False,不执行    print('不会执行')if 'hello':   # 非空 → True,执行    print('会执行')if []:        # 空列表 → False    print('不会执行')
C++ 则要显式写条件,比如判断指针/容器是否为空:
int* p = nullptr;if (p) { }                // C++ 指针可以直接当 bool 用(nullptr 为假)std::string s = "";if (!s.empty()) { }       // 字符串要调用 empty()

6.4 赋值运算符

6.4.1 链式赋值:a = b = 10

Python 和 C++ 都支持,把同一个值赋给多个变量,从右往左依次赋值:

# Pythona = b = 10print(a, b)     # 10 10
// C++int a, b;a = b = 10;     // 先 b = 10,再 a = 10

6.4.2 多元赋值:a, b = 10, 20(Python 独有)

Python 可以一行给多个变量赋不同的值,左边是变量元组 ,右边是对应的值元组:

a, b = 1020print(a, b)     # 10 20
C++ 没有这个语法,只能分开写或用 std::tie
int a = 10, b = 20;// 或者std::tie(a, b) = std::make_tuple(1020);

6.4.3 变量交换(重点)

传统写法(借助临时变量,两门语言通用):

# Pythontmp = aa = bb = tmp
// C++int tmp = a;a = b;b = tmp;// 或者用标准库std::swap(a, b);
Python 特有写法(利用多元赋值,一行搞定):
a, b = b, a     # 右侧先把 (b, a) 打包,再解包给 a, bprint(a, b)
这个写法能生效的原理:右边的 b, a 会先求值打包成一个元组 ,再整体赋给左边。所以不存在"先改了 a 导致 b 取错"的问题,也不需要临时变量。

6.4.4 复合赋值运算符

+= -= *= /= %= 等,两门语言含义一致:a += 1 等价于 a = a + 1

# Pythona = 10a += 1print(a)        # 11
// C++int a = 10;a += 1;std::cout << a << std::endl;   // 11

6.4.5 重点差异:Python 不支持 ++ --

C++ 里 ++ / -- 有前置后置之分,极易混淆:

int a = 10;int x = a++;      // 后置:先取 a 的值 10 赋给 x,再自增 → x = 10, a = 11int y = ++a;      // 前置:先自增再取 a 的值 → a = 12, y = 12
Python 故意砍掉了 ++ --,因为前置后置太容易出错,不符合 Python 追求简洁直观的理念。需要自增自减时,直接用复合赋值:
# Python:不支持 a++ 或 ++a,会语法报错a += 1     # 正确a -= 1     # 正确
注意一个坑:Python 里 ++a 不会报语法错,但它是 +(+a),也就是对  a 连续取两次正号,值不变!新手看到不报错就以为自增成功了,其实 a 根本没变。调试时尤其要小心。

6.5 位运算符

两门语言的位运算符符号完全一样&(按位与)、|(按位或)、~(按位取反)、^(按位异或)、<<(左移)、>>(右移)。
以 a = 5(二进制 0101)、 b = 3(二进制 0011)为例:
# Pythona, b = 53print(a & b)     # 1   0101 & 0011 = 0001print(a | b)     # 7   0101 | 0011 = 0111print(a ^ b)     # 6   0101 ^ 0011 = 0110(相同为0,不同为1print(~a)        # -6  按位取反:~5 = -6print(a <1)    # 10  左移1位:0101 → 1010,相当于 ×2print(a >> 1)    # 2   右移1位:0101 → 0010,相当于 ÷2
// C++int a = 5, b = 3;std::cout << (a & b) << std::endl;     // 1std::cout << (a | b) << std::endl;     // 7std::cout << (a ^ b) << std::endl;     // 6std::cout << (~a) << std::endl;        // -6std::cout << (a <1) << std::endl;    // 10std::cout << (a >> 1) << std::endl;    // 2
常用技巧(面试高频):
  • 判断奇偶:x & 1(为 1 是奇数,为 0 是偶数),比 x % 2 更快。
  • 乘 2 / 除 2:x << 1 / x >> 1
  • 交换两个数:a ^= b; b ^= a; a ^= b;(了解即可,实际开发用多元赋值更清晰)。
位运算对比小差异:Python 的整数是无限位宽的,对负数做 >> 是 算术右移(高位补 1),C++ 对有符号负数的右移行为由实现决定(现代编译器基本也是算术右移)。日常正数运算两者表现一致,不必深究,知道有这回事即可。

6.6 身份运算符 is / is not

is 比较的是是不是同一个对象(内存地址),和比较值相等的 == 是两码事:

a = [123]b = [123]print(a == b)     # True   值相等(内容一样)print(a is b)     # False  不是同一个对象(内存地址不同)
c = aprint(a is c)     # True   指向同一个对象
// C++ 的对应概念:比较地址 与 比较值int x = 5;int* p1 = &x;int* p2 = &x;std::cout << (p1 == p2) << std::endl;   // 1  指向同一块地址std::cout << (*p1 == *p2) << std::endl; // 1  指向的值相等
经典坑a is None 判断是否为空;a == None 判断值是否相等。判空习惯用 is None。另外小整数在 Python 里会被缓存,a = 1; b = 1; a is b 可能为 True,但这属于实现细节,不要依赖 is 比较整数,要判断值就用  ==

6.7 成员运算符 in / not in(补充)

判断某个元素在不在一个容器(字符串、列表、元组)里:

print('a' in 'hello')          # Falseprint('l' in 'hello')          # Trueprint(3 in [1, 2, 3])          # Trueprint(5 not in [1, 2, 3])      # True
C++ 没有 in 关键字,需要自己查找:
#include #include std::string s = "hello";bool has_l = s.find('l') != std::string::npos;        // trueint arr[] = {123};bool has_3 = std::find(std::begin(arr), std::end(arr), 3) != std::end(arr);  // true

6.8 运算符优先级

整体优先级和 C++ 高度相似,从高到低大致为:

差别最大的一个:Python 里 ** 优先级高于一元负号,所以 -3 ** 2 的结果是 -9(先算 3**2 再取负),而 C++ 里没有乘方运算符,不存在这个纠结。  实战建议:别硬背优先级,拿不准就加括号,代码可读性永远第一。

七、总结:一张表记住所有差异

一句话总结两门语言的哲学差异:
C++ 是"铁板钉钉"——类型、内存、运算符行为都在编译期定死,性能可控但写起来啰嗦、容易踩底层坑;Python 是"随遇而安"——类型动态推断、语法追求简洁直观,砍掉了 ++ -- 这种容易混淆的特性,开发效率高,适合把精力放在解决问题本身。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/200375