Python 基本语法:变量、数据类型与 print 的秘密

文章目录

一、从一个需求开始:写一个计算器

在正式讨论语法之前,先设想一个真实场景:需要写一个简易的加减乘除计算器,用户输入两个数字,选择运算方式,程序输出结果。

这个看似简单的需求,实际上涵盖了 Python 基本语法中最核心的概念:
计算器需求
接收用户输入

→ input() → str 类型
获取运算符

→ str 判断
数值计算

→ int/float 类型
输出结果

→ print() 输出
类型转换

str → int/float
结果格式化

保留小数位
根据运算符

调用对应计算

下面的内容将按照这个顺序展开:每个概念的引入都对应计算器开发中的具体步骤,让语法不再是抽象的规则,而是解决问题的工具。

二、变量与赋值:给数据起个名字

2.1 什么是变量

变量就是一个存放数据的"盒子"。Python 里创建一个变量只需要一行代码:

python 复制代码
name = "Alice"
age = 28
height = 1.65
is_student = False

等号 = 在 Python 中不是"等于"的意思,而是赋值运算符 ------将右侧的值存入左侧的变量中。"name = "Alice"" 的含义是:创建一个名为 name 的盒子,把字符串 "Alice" 放进去。

可以用 type() 函数查看任意数据的类型:

python 复制代码
>>> type("Alice")
<class 'str'>

>>> type(28)
<class 'int'>

>>> type(1.65)
<class 'float'>

>>> type(False)
<class 'bool'>

2.2 变量命名规范

Python 的变量名有以下硬性规则:

  • 只能包含字母、数字、下划线 _
  • 不能以数字开头(如 2name 非法)
  • 不能使用 Python 保留字(如 ifforclass 等)
  • 大小写敏感(Namename 是两个不同的变量)

除了硬性规则,还有一个行业惯例 :Python 社区统一使用蛇形命名法(snake_case)------所有字母小写,单词之间用下划线分隔。

python 复制代码
# 符合规范的命名
user_name = "Bob"
total_price = 129.8
is_vip_member = True

# 不推荐的命名(虽然合法,但不符合社区惯例)
userName = "Bob"     # 驼峰命名,Python 社区不常用
TotalPrice = 129.8   # 帕斯卡命名,用于类名而非变量

为什么有"社区惯例"这种东西? 代码不是写给自己看的------接手代码的人、Review 代码的同事、调用 API 的开发者,都需要快速理解变量名代表什么。一致的命名风格比"好不好看"更重要。

2.3 变量在计算器中的应用

回到计算器场景。需要存储用户输入的两个数字:

python 复制代码
# 获取用户输入
a = input("请输入第一个数字: ")   # input() 返回的是字符串
b = input("请输入第二个数字: ")

print(type(a))   # <class 'str'> ------ 拿到的是字符串,不是数字
print(type(b))   # <class 'str'>

这里出现了一个关键问题:input() 返回的始终是字符串类型,即使输入的是 100,在程序内部也是 "100" 而不是数字 100。理解这一点,是掌握 Python 类型系统的第一步。

三、六大基本数据类型

Python 的数据类型可以分为两大类:原子类型 (不可再分)和容器类型(可容纳多个数据)。对于计算器场景,重点掌握以下六种:

类型 名称 示例 是否原子
int 整数 42, -7, 0
float 浮点数 3.14, -0.5, 2.0
str 字符串 "hello", 'world'
bool 布尔值 True, False
list 列表 [1, 2, 3]
dict 字典 {"name": "Alice", "age": 28}

3.1 为什么需要区分类型

不同类型支持的操作不同。数字类型可以做加减乘除,字符串类型可以做拼接和切片:

python 复制代码
# 数字相加
>>> 10 + 5
15

# 字符串拼接
>>> "10" + "5"
'105'   # 结果是字符串 "105",不是数字 15!

这意味着:如果想让字符串 "10""5" 相加得到 15,必须先将它们转换为数字类型。

3.2 用 type() 验证计算器中的数据类型

输入 103,选择除法运算。不同类型会直接影响计算结果:

python 复制代码
# 场景1: 没有转换------字符串除法会报错
>>> "10" / "3"
TypeError: unsupported operand type(s) for /: 'str' and 'str'

# 场景2: 转换为浮点数------得到精确小数
>>> float("10") / float("3")
3.3333333333333335

第二行中,float("10") 将字符串 "10" 转换为浮点数 10.0,再进行除法运算。

四、数字运算与浮点数精度问题

除了加减乘除,Python 还提供了几个在特定场景下非常有用的运算符。

python 复制代码
a, b = 10, 3

print(a + b)   # 加法: 13
print(a - b)   # 减法: 7
print(a * b)   # 乘法: 30
print(a / b)   # 除法: 3.3333333333333335
print(a // b)  # 整除: 3(向下取整)
print(a % b)   # 取模: 1(10 除以 3 余 1)
print(a ** b)  # 幂运算: 10 的 3 次方 = 1000

其中有两个值得特别注意的运算符:

  • // 整除 :计算结果只保留整数部分,10 // 3 等于 3 而非 3.33
  • % 取模(取余) :计算除法后的余数,常用于判断奇偶性(n % 2 == 0 是偶数)、周期性操作等

4.2 浮点数精度问题:0.1 + 0.2 != 0.3

大多数编程语言都有这么一出------Python 里也不例外:

python 复制代码
>>> 0.1 + 0.2 == 0.3
False

>>> 0.1 + 0.2
0.30000000000000004

这不是 Python 的 Bug,也不是代码写错了,而是二进制浮点数运算的固有特性------C、Java、JavaScript 遇到同样的情况,反应一模一样。

4.2.1 为什么会这样?

计算机内部使用二进制(Base 2)存储小数,而十进制的 0.1(即 1/10)在二进制中是一个无限循环小数:

复制代码
0.0001100110011001100110011001100110011001100110011... (0011 循环)

IEEE 754 双精度浮点数只有 53 位有效精度,无法精确表示 0.1。计算机实际存储的是最接近它的分数:

python 复制代码
>>> (0.1).as_integer_ratio()   # 查看 0.1 的二进制分数表示
(3602879701896397, 9007199254740992)
# 也就是: 3602879701896397 / 2**55

这个分数换算成十进制后,比真正的 0.1 多出了微小的正向误差。0.2 同样也存在类似误差。两者相加时误差累积,最终结果与 0.3(也是一个不精确的近似值)并不完全相等。

用图示理解误差来源:
计算机存储的(IEEE 754 浮点数)
我们看到的(十进制)
存储
存储
存储
+
+
不相等
0.1
0.2
0.3
0.1000000000000000055...
0.200000000000000011...
0.299999999999999988...
0.30000000000000004

4.2.2 日常开发中如何处理

不要用 == 比较浮点数 。Python 官方推荐使用 math.isclose()

python 复制代码
>>> import math
>>> math.isclose(0.1 + 0.2, 0.3)
True

当需要精确十进制运算时 (财务、账目等场景),使用 decimal 模块:

python 复制代码
>>> from decimal import Decimal
>>> Decimal("0.1") + Decimal("0.2") == Decimal("0.3")
True

注意 :必须用字符串 "0.1" 初始化 Decimal,如果写成 Decimal(0.1),二进制误差会随着 0.1 一起传入,== 比较仍然会返回 False

当需要累加大量浮点数时 ,使用 math.fsum() 控制误差累积:

python 复制代码
>>> import math
>>> sum([0.1] * 10) == 1.0
False
>>> math.fsum([0.1] * 10) == 1.0
True

在计算器场景中,通常只需在输出时格式化保留两位小数:

python 复制代码
result = a / b
print(f"结果是: {result:.2f}")   # .2f 表示保留两位小数
# 结果是: 3.33

五、字符串:从用户输入到格式化输出

5.1 字符串的创建与引号规则

Python 中三种引号都可以创建字符串:

python 复制代码
s1 = "双引号"
s2 = '单引号'        # 在字符串内包含引号时换用,避免转义
s3 = """三引号
        可以跨行"""   # 三引号支持多行文本

两种引号(""'')在功能上完全等价,选择哪种纯粹取决于字符串内容是否包含同类引号。

5.2 字符串的索引与切片

字符串中的每个字符都有一个位置编号,从 0 开始:

python 复制代码
>>> text = "Python"
>>> text[0]
'P'
>>> text[-1]    # 负数索引从右往左数,-1 是最后一个字符
'n'
>>> text[0:3]  # 切片语法:左闭右开,提取索引 0、1、2
'Pyt'
>>> text[::2]  # 第三个参数表示步长,每隔一个字符取一个
'Pto'

5.3 f-string 格式化:Python 3.6+ 的最佳实践

f-string(格式化字符串字面量)是目前最推荐的字符串格式化方式。在字符串前加 f 前缀,就可以在 {} 中直接插入变量或表达式:

python 复制代码
name = "Alice"
age = 28

# 基本用法
print(f"我叫 {name},今年 {age} 岁。")
# 输出: 我叫 Alice,今年 28 岁。

# 嵌入表达式
print(f"明年就 {age + 1} 岁了。")
# 输出: 明年就 29 岁了。

# 保留小数位
pi = 3.1415926
print(f"π 保留两位小数是 {pi:.2f}")
# 输出: π 保留两位小数是 3.14

# 数字千分位格式化
population = 1412000000
print(f"人口: {population:,}")
# 输出: 人口: 1,412,000,000

回到计算器场景,用 f-string 输出结果:

python 复制代码
result = a / b
print(f"{a} ÷ {b} = {result:.4f}")
# 输入 a=10, b=3 时,输出: 10 ÷ 3 = 3.3333

5.4 字符串的不可变性

Python 中的字符串是不可变对象------创建之后不能直接修改。如果尝试对字符串的某个位置赋值,会报错:

python 复制代码
>>> s = "hello"
>>> s[0] = "H"
TypeError: 'str' object does not support item assignment

这不是限制,而是设计选择。不可变对象让程序更容易推理------一个字符串一旦创建,它的值永远不会因为某个意外操作而改变。如果需要"修改"字符串,实际上是创建了一个新的字符串:

python 复制代码
>>> s = "hello"
>>> s_new = "H" + s[1:]   # 创建新字符串,旧字符串不变
>>> s_new
'Hello'
>>> s                      # 原字符串保持不变
'hello'

六、布尔值:程序做决策的基础

布尔类型只有两个值:True(真)和 False(假)。在计算器场景中,可以用布尔值判断运算是否合法:

python 复制代码
# 判断除数是否为 0
divisor = 3
is_valid = divisor != 0
print(is_valid)   # True

if divisor == 0:
    print("除数不能为 0")
else:
    print(f"结果是 {10 / divisor}")

6.1 比较运算符

运算符 含义 示例 结果
== 等于 5 == 5 True
!= 不等于 5 != 3 True
> 大于 5 > 3 True
< 小于 5 < 3 False
>= 大于等于 5 >= 5 True
<= 小于等于 5 <= 3 False

6.2 Python 特有的链式比较

Python 允许一种在其他语言中很少见的比较写法------链式比较

python 复制代码
>>> 0 < x < 10          # 等价于 (0 < x) and (x < 10)
>>> 0 < age <= 18       # 年龄在 0 到 18 岁之间(包含 18)
>>> -1 < x < 1          # x 在 -1 到 1 之间

这种写法不仅更简洁,而且在数学上更直观:0 < x < 10 直接表达"x 介于 0 和 10 之间"这个概念,而不是拆成两个独立条件。

七、类型转换:让数据从一种形态变成另一种

类型转换是计算器开发中最核心的步骤之一。用户的输入永远是字符串,数学运算需要数字,输出结果又需要变回字符串------这个过程贯穿整个程序:
输出阶段
计算阶段
转换阶段
输入阶段
input()
str 类型

如 '10', '3'
int() / float()
数值类型

10, 3
算术运算

a / b
float 类型

3.3333...
f-string 格式化

保留小数位
str 类型

'3.3333'

7.1 常用类型转换函数

python 复制代码
# 字符串 → 整数
int("42")       # → 42
int("  7  ")    # → 7(自动忽略前后空格)

# 字符串 → 浮点数
float("3.14")   # → 3.14
float("42")     # → 42.0(整数转浮点数)

# 数字 → 字符串
str(42)         # → "42"
str(3.14)       # → "3.14"
str(True)       # → "True"(布尔转字符串)

# 浮点数 → 整数(截断小数部分,不四舍五入)
int(3.99)       # → 3(不是 4!)

# 字符串 → 布尔值(非空字符串为 True)
bool("hello")   # → True
bool("")        # → False
bool("0")       # → True(非空字符串)
bool(0)         # → False(数字 0 本身是 False)

7.2 转换失败的处理

当类型转换无法完成时,Python 会抛出 ValueError

python 复制代码
>>> int("hello")
ValueError: invalid literal for int() with base 10: 'hello'

>>> float("3.14.15")
ValueError: could not convert string to float: '3.14.15'

在实际开发中,应该在转换之前先验证字符串的内容是否符合预期:

python 复制代码
user_input = "10"

if user_input.isdigit():          # 判断字符串是否全由数字组成
    number = int(user_input)
    print(f"转换成功: {number}")
else:
    print(f"'{user_input}' 不是有效数字")

八、注释:写给未来的自己

代码写完后,最常见的困惑不是"这段代码是做什么的",而是"为什么这样做"。注释记录的是"为什么",而不是"做了什么"------代码本身已经说明了"做了什么",好的注释应该解释那些从代码本身看不出来的决策理由。

python 复制代码
# 计算圆的面积
area = 3.14 * radius ** 2

# 为什么要用 3.14 而不是 math.pi?
# ------因为用户要求精确到小数点后两位,3.14 已经足够
# ------math.pi 的精度在这里反而是过度工程

8.1 单行注释与多行注释

python 复制代码
# 这是一个单行注释

"""
这是一个多行注释(三引号字符串)
常用于模块开头的说明文档(docstring)
"""

def greet(name):
    """
    向指定用户打招呼。

    参数:
        name: 用户名字符串
    返回:
        打招呼的字符串
    """
    return f"你好,{name}!"

三引号字符串在函数内部作为第一个语句出现时,就成了该函数的文档字符串(docstring) 。Python 的内置 help() 函数会读取并显示它:

python 复制代码
>>> help(greet)

Help on function greet in module __main__:

greet(name)
    向指定用户打招呼。
    
    参数:
        name: 用户名字符串
    返回:
        打招呼的字符串

九、实战:构建一个简易计算器

整合以上所有概念,构建完整的计算器程序:

python 复制代码
"""
简易计算器 v1.0
支持加减乘除,支持除数为零的检查
"""

def calculator():
    """运行一次计算器交互"""
    print("=" * 30)
    print("欢迎使用简易计算器")
    print("=" * 30)

    # 第一步:获取用户输入(input 返回 str)
    num1_str = input("请输入第一个数字: ").strip()
    operator = input("请输入运算符 (+ - * /): ").strip()
    num2_str = input("请输入第二个数字: ").strip()

    # 第二步:验证输入是否为有效数字(isdigit 检查)
    if not num1_str.replace(".", "", 1).replace("-", "", 1).isdigit():
        print(f"错误: '{num1_str}' 不是有效数字")
        return

    if not num2_str.replace(".", "", 1).replace("-", "", 1).isdigit():
        print(f"错误: '{num2_str}' 不是有效数字")
        return

    # 第三步:类型转换(str → float,用于精确除法运算)
    num1 = float(num1_str)
    num2 = float(num2_str)

    # 第四步:根据运算符分支处理
    # 特别处理除法:除数为零时给出友好提示而非崩溃
    if operator == "+":
        result = num1 + num2
        symbol = "+"
    elif operator == "-":
        result = num1 - num2
        symbol = "-"
    elif operator == "*":
        result = num1 * num2
        symbol = "×"
    elif operator == "/":
        if num2 == 0:
            print("错误: 除数不能为零")
            return
        result = num1 / num2
        symbol = "÷"
    else:
        print(f"错误: 不支持的运算符 '{operator}'")
        return

    # 第五步:格式化输出(f-string + 保留小数位)
    if result == int(result):
        # 如果结果是整数,不显示小数部分
        print(f"{num1} {symbol} {num2} = {int(result)}")
    else:
        # 如果结果是小数,保留两位小数
        print(f"{num1} {symbol} {num2} = {result:.2f}")

if __name__ == "__main__":
    calculator()

运行效果:

复制代码
==============================
欢迎使用简易计算器
==============================
请输入第一个数字: 10
请输入运算符 (+ - * /): /
请输入第二个数字: 3
10 ÷ 3 = 3.33

十、print 函数:你可能不知道的参数

print() 是 Python 中最常用的函数之一,但很多人只用过它最基本的用法。事实上 print 还有几个实用参数:

python 复制代码
# sep: 多个参数之间的分隔符,默认是空格
print("Hello", "World", "Python", sep=" | ")
# 输出: Hello | World | Python

# end: 打印结束后的字符,默认是换行符 \n
print("正在加载", end="")
print("...", end="")
print("完成")
# 输出: 正在加载...完成(所有内容在同一行)

# file: 指定输出目标,默认是 sys.stdout(屏幕)
# 可重定向到文件
with open("result.txt", "w", encoding="utf-8") as f:
    print(f"计算结果: {result}", file=f)
# 内容被写入文件而非显示在屏幕上

# flush: 是否立即刷新输出(常用于进度条显示)
import time
for i in range(5):
    print(f"进度 {i+1}/5", end="\r", flush=True)
    time.sleep(0.5)
# \r 把光标回到行首,覆盖打印同一行内容

写在最后

本篇从一个计算器的实际需求出发,依次覆盖了变量、类型系统、数字运算、字符串处理、布尔值、类型转换和 print 函数等核心概念。这些内容并非孤立------在计算器的开发过程中,每一步都用到了前面学过的知识:用户输入产生字符串,字符串需要转换才能参与计算,计算结果又需要格式化才能友好输出。

这种"环环相扣"的感觉,正是编程有意思的地方。

如果本文有帮助,欢迎点赞、关注。Python 基础系列会持续更新。

相关推荐
曲幽1 小时前
FastAPI 文件上传避坑全指南:分块存盘、类型校验与安全兜底
python·upload·fastapi·web·file·chunk·validate·filetype
m0_747854522 小时前
如何创建CDB公共用户_C##前缀强制规则与CONTAINER=ALL
jvm·数据库·python
Absurd5872 小时前
SQL如何高效提取每组首条记录 ROW_NUMBER优化策略
jvm·数据库·python
2501_914245932 小时前
CSS如何更改鼠标悬停时的指针样式_设置cursor属性为pointer或not-allowed
jvm·数据库·python
四维迁跃2 小时前
Go语言如何做SSE推送_Go语言Server-Sent Events教程【技巧】
jvm·数据库·python
qq_372154232 小时前
JavaScript中字符串split方法转换为数组的细节
jvm·数据库·python
rannn_1112 小时前
3h速通Python:用Java的思维看懂Python
开发语言·python·ai·ai agent·大模型应用开发
qq_372154232 小时前
Python中如何快速创建全零数组_使用NumPy的zeros函数初始化内存
jvm·数据库·python
上弦月-编程2 小时前
C语言位运算:从入门到精通
运维·c语言·开发语言·vscode·算法·leetcode·极限编程