Python 全面语法指南
前言
1. 什么是编程?
编程就像是教电脑做事的过程。想象你有一个非常听话但很笨的助手,你需要用它能理解的语言(编程语言)一步一步地告诉它该做什么。
- 你 = 程序员(下达指令的人)
- Python = 你和电脑沟通的语言
- 电脑 = 执行指令的助手
2. Python 的特点
Python 之所以适合初学者,是因为它:
- 像英语一样易读 - 代码看起来像自然语言
- 简洁明了 - 用很少的代码完成很多功能
- 功能强大 - 从简单计算到人工智能都能做
- 免费开源 - 任何人都可以免费使用
3. 程序的基本结构
一个 Python 程序就像做菜的食谱:
1. 准备材料(定义变量) 2. 处理材料(执行操作) 3. 呈现结果(输出信息)
1. Python 基础语法
1.1 变量与数据类型
什么是变量?
想象一下,变量就像是一个贴了标签的储物盒。你可以在盒子里存放不同的东西,通过标签来找到它。
- 变量名 = 标签名
- 变量值 = 盒子里的东西
- 赋值操作 = 把东西放进盒子并贴上标签
# 就像给储物盒贴标签并放入物品 name = "小明" # 在"name"盒子里放入"小明" age = 18 # 在"age"盒子里放入18 height = 1.75 # 在"height"盒子里放入1.75 is_student = True # 在"is_student"盒子里放入True # 查看盒子里的东西 print(name) # 输出: 小明 print(age) # 输出: 18 # 可以更换盒子里的物品 name = "小红" print(name) # 输出: 小红数据类型: 数据的分类
就像物品有不同的类别(食物、衣服、工具),python中的数据也有不同的类型:
- 整数 (int) - 像数苹果的个数,没有小数
- 浮点数 (float) - 像量身高,有小数
- 字符串 (str) - 像写文字,用引号包围
- 布尔值 (bool) - 像判断题,只有对/错
# 1. 整数 (int) - 像计数用的整数 student_count = 45 age = 18 # 2. 浮点数 (float) - 像带小数的价格 price = 19.99 pi = 3.14159 # 3. 字符串 (str) - 像文字描述 name = "李华" message = '他说:"你好!"' # 4. 布尔值 (bool) - 像开关,只有开/关两种状态 is_raining = True has_homework = False # 查看物品的类别标签 print(type(age)) # <class 'int'> - 整数类型 print(type(price)) # <class 'float'> - 小数类型 print(type(name)) # <class 'str'> - 字符串类型 print(type(is_raining)) # <class 'bool'> - 布尔类型类型转换:改变物品的包装
有时候我们需要把一种类型转换成另一种类型:
# 字符串转数字 - 把文字描述的数字变成真正的数字 text_number = "123" real_number = int(text_number) # 把"123"文字变成123数字 print(real_number) # 123 print(type(real_number)) # <class 'int'> # 数字转字符串 - 给数字加上文字说明 score = 95 score_text = str(score) print("我的分数是:" + score_text) # 我的分数是:95 # 浮点数转整数 - 注意会丢失小数部分(像取整) price = 19.99 whole_price = int(price) print(whole_price) # 19(小数部分被去掉了)1.2 运算符与表达式
算术运算符:数学计算
Python 可以做各种数学运算,就像计算器一样:
- 算术运算:加减乘除
- 比较运算:比较大小
- 逻辑运算:组合条件
# 基本运算 a = 10 b = 3 print(a + b) # 13 - 加法 print(a - b) # 7 - 减法 print(a * b) # 30 - 乘法 print(a / b) # 3.333... - 除法 print(a // b) # 3 - 整除(只取整数部分,像小学除法) print(a % b) # 1 - 取余(求余数,像分东西剩下的) print(a ** b) # 1000 - 幂运算(10的3次方)比较运算符:比较大小
用来比较两个值的关系:
x = 10 y = 5 print(x == y) # False - 等于吗? print(x != y) # True - 不等于吗? print(x > y) # True - 大于吗? print(x < y) # False - 小于吗? print(x >= y) # True - 大于等于吗? print(x <= y) # False - 小于等于吗?逻辑运算符:组合条件
用来把多个条件组合在一起判断:
# 与运算 (and) - 两个条件都要满足,像"既要...又要..." is_weekend = True has_money = True can_shopping = is_weekend and has_money print(can_shopping) # True - 既是周末又有钱才能购物 # 或运算 (or) - 只要一个条件满足就行,像"要么...要么..." is_holiday = False is_weekend = True can_rest = is_holiday or is_weekend print(can_rest) # True - 节假日或周末都可以休息 # 非运算 (not) - 取反,像说反话 is_raining = True can_play_outside = not is_raining print(can_play_outside) # False - 不下雨才能出去玩1.3 输入与输出
- 输入:你告诉程序信息(像回答问题)
- 输出:程序告诉你结果(像程序说话)
获取用户输入:和程序对话
# input() 函数会暂停程序,等待用户输入 # 就像程序在问你问题,你回答后程序继续运行 name = input("请输入你的名字:") # 程序问你的名字 age = input("请输入你的年龄:") # 程序问你的年龄 print("你好," + name + "!") # 程序向你打招呼 print("你今年" + age + "岁了") # 程序说出你的年龄输出信息:程序告诉你结果
# 基本输出 - 程序说话 print("Hello, World!") # 程序说:Hello, World! # 输出多个值 - 程序说一段话 name = "小明" score = 95 print("学生:", name, "分数:", score) # 学生: 小明 分数: 95 # 格式化输出(推荐!更清晰) - 程序说一句完整的话 print(f"学生:{name},分数:{score}") # 学生:小明,分数:95 # 复杂的格式化 - 程序做计算并告诉你结果 price = 19.99 quantity = 3 total = price * quantity print(f"单价:{price}元,数量:{quantity},总价:{total:.2f}元") # 输出:单价:19.99元,数量:3,总价:59.97元2. Python 控制结构
2.1 条件语句:让程序做决定
就像生活中的选择:
- 如果下雨,就带伞
- 否则如果阴天,就带外套
- 否则,什么都不带
if 语句 - 最基本的条件判断
age = 18 if age >= 18: print("你已经成年了!") # 如果年龄≥18,执行这里 print("可以考驾照了") # 可以写多行代码 if-else 语句 - 二选一 python age = 16 if age >= 18: print("成年") # 条件成立时执行 else: print("未成年") # 条件不成立时执行if-elif-else 语句 - 多条件判断
score = 85 if score >= 90: print("优秀") # 90分以上 elif score >= 80: # 80-89分 print("良好") elif score >= 70: # 70-79分 print("中等") elif score >= 60: # 60-69分 print("及格") else: # 60分以下 print("不及格")嵌套条件 - 条件中的条件
age = 20 has_license = True has_car = False if age >= 18: # 第一层判断:年龄够吗? if has_license: # 第二层判断:有驾照吗? if has_car: # 第三层判断:有车吗? print("可以开车出门") else: print("有驾照但没车") else: print("需要先考驾照") else: print("年龄不够,不能开车")2.2 循环语句:重复执行任务
就像重复做同样的事情:
- for循环:知道要重复多少次(像数1到10)
- while循环:不知道要重复多少次,直到条件满足(像猜密码直到正确)
while 循环 - 当条件满足时重复执行
# 计数器循环 - 像数数 count = 0 while count < 5: # 当count小于5时重复 print(f"这是第{count + 1}次循环") count += 1 # 重要:每次循环count加1 # 实际应用:输入验证 - 直到输入正确才停止 while password != "123456": # 当密码不是"123456"时重复 password = input("请输入密码:") print("密码正确!")for 循环 - 遍历序列中的每个元素
# 遍历列表 - 像逐个检查购物清单 fruits = ["苹果", "香蕉", "橙子", "草莓"] for fruit in fruits: # 对每个水果执行一次 print(f"我喜欢吃{fruit}") # 遍历字符串 - 像逐个看字母 name = "Python" for char in name: print(char) # 依次输出:P, y, t, h, o, nrange() 函数 - 生成数字序列
# 生成 0-4 的数字 for i in range(5): print(i) # 输出: 0, 1, 2, 3, 4 # 生成 2-5 的数字 for i in range(2, 6): print(i) # 输出: 2, 3, 4, 5 # 生成 1-10 的奇数 for i in range(1, 11, 2): # 从1开始,到11结束,步长为2 print(i) # 输出: 1, 3, 5, 7, 9循环控制语句
# break - 提前结束整个循环(像紧急停止) print("break示例:") for i in range(10): if i == 5: break # 当i等于5时,立即结束整个循环 print(i) # 只输出: 0, 1, 2, 3, 4 # continue - 跳过本次循环(像跳过这一轮) print("continue示例:") for i in range(10): if i % 2 == 0: # 如果是偶数 continue # 跳过本次循环的剩余代码 print(i) # 只输出奇数: 1, 3, 5, 7, 93. Python 数据结构
3.1 列表 (List) - 有序的可变序列
列表的基本概念
列表就像是一个动态的购物车或者可编辑的任务清单,可以存放多个物品。
- 有序:每个元素都有固定的位置
- 可变:可以随时添加、删除、修改元素
- 可重复:允许包含重复的元素
- 混合类型:可以存放不同类型的数据
# 创建列表的各种方式 empty_list = [] # 空列表 shopping_list = ["苹果", "牛奶", "面包"] # 字符串列表 numbers = [1, 2, 3, 4, 5] # 整数列表 mixed_list = [1, "苹果", 3.14, True] # 混合类型列表 nested_list = [[1, 2], [3, 4], [5, 6]] # 嵌套列表(列表的列表) print(f"购物清单: {shopping_list}") print(f"混合列表: {mixed_list}") print(f"嵌套列表: {nested_list}")列表的索引和切片详解
索引
索引就像门牌号或者座位号,用来精确定位列表中的每个元素。
- 正索引:从前往后编号,从 0 开始
- 负索引:从后往前编号,从 -1 开始
# 创建一个列表来演示 fruits = ["苹果", "香蕉", "橙子", "草莓", "葡萄", "芒果"] print("列表:", fruits) print("长度:", len(fruits)) # 正索引演示 print("\n=== 正索引 ===") print(f"fruits[0] = {fruits[0]}") # 第1个元素 print(f"fruits[1] = {fruits[1]}") # 第2个元素 print(f"fruits[2] = {fruits[2]}") # 第3个元素 print(f"fruits[3] = {fruits[3]}") # 第4个元素 # 负索引演示 print("\n=== 负索引 ===") print(f"fruits[-1] = {fruits[-1]}") # 最后1个元素 print(f"fruits[-2] = {fruits[-2]}") # 倒数第2个元素 print(f"fruits[-3] = {fruits[-3]}") # 倒数第3个元素索引的可视化理解
列表: ["苹果", "香蕉", "橙子", "草莓", "葡萄", "芒果"] 正索引: 0 1 2 3 4 5 负索引: -6 -5 -4 -3 -2 -1
切片
切片就像切蛋糕,可以获取列表的一部分。基本语法:
列表[开始:结束:步长]
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print("原始列表:", numbers) # 基本切片 print("\n=== 基本切片 ===") print(f"numbers[2:6] = {numbers[2:6]}") # 索引2到6(不包括6) print(f"numbers[:4] = {numbers[:4]}") # 从开始到索引4 print(f"numbers[5:] = {numbers[5:]}") # 从索引5到结束 print(f"numbers[:] = {numbers[:]}") # 整个列表的副本切片参数详解:
| 参数 | 含义 | 默认值 | 示例 |
|---|---|---|---|
start | 开始位置(包含) | 0 | [2:] 从索引2开始 |
stop | 结束位置(不包含) | 列表长度 | [:5] 到索引5结束 |
step | 步长(每隔几个取一个) | 1 | [::2] 每隔一个取一个 |
各种切片操作详解:切片
访问列表元素
fruits = ["苹果", "香蕉", "橙子", "草莓"] # 正索引:从前往后数(从0开始) print(fruits[0]) # 苹果 - 第一个元素(索引0) print(fruits[1]) # 香蕉 - 第二个元素(索引1) # 负索引:从后往前数(从-1开始) print(fruits[-1]) # 草莓 - 最后一个元素 print(fruits[-2]) # 橙子 - 倒数第二个元素 # 切片:获取子列表 [开始:结束:步长] print(fruits[1:3]) # ['香蕉', '橙子'] - 索引1到3(不包括3) print(fruits[:2]) # ['苹果', '香蕉'] - 从开始到索引2 print(fruits[::2]) # ['苹果', '橙子'] - 每隔一个取一个修改列表
添加元素
fruits = ["苹果", "香蕉"] # append() - 在末尾添加单个元素 fruits.append("橙子") print(fruits) # ['苹果', '香蕉', '橙子'] # extend() - 在末尾添加多个元素(合并列表) fruits.extend(["草莓", "葡萄"]) print(fruits) # ['苹果', '香蕉', '橙子', '草莓', '葡萄'] # insert() - 在指定位置插入元素 fruits.insert(1, "梨") # 在索引1的位置插入"梨" print(fruits) # ['苹果', '梨', '香蕉', '橙子', '草莓', '葡萄'] # + 运算符合并列表 more_fruits = ["芒果", "菠萝"] all_fruits = fruits + more_fruits print(all_fruits) # 两个列表合并删除元素
fruits = ["苹果", "梨", "香蕉", "橙子", "梨", "草莓"] # del - 按索引删除 del fruits[1] # 删除索引1的元素(第一个"梨") print(fruits) # ['苹果', '香蕉', '橙子', '梨', '草莓'] # pop() - 删除并返回指定位置的元素 removed_fruit = fruits.pop(2) # 删除索引2的元素("橙子") print(f"删除了: {removed_fruit}") # 删除了: 橙子 print(fruits) # ['苹果', '香蕉', '梨', '草莓'] # remove() - 删除第一个匹配的元素 fruits.remove("梨") # 删除第一个"梨" print(fruits) # ['苹果', '香蕉', '草莓'] # clear() - 清空整个列表 fruits.clear() print(fruits) # []修改元素
fruits = ["苹果", "香蕉", "橙子"] # 直接赋值修改 fruits[1] = "葡萄" print(fruits) # ['苹果', '葡萄', '橙子'] # 切片赋值(批量修改) fruits[0:2] = ["芒果", "菠萝"] # 替换前两个元素 print(fruits) # ['芒果', '菠萝', '橙子'] # 切片插入(不替换,而是插入) fruits[1:1] = ["西瓜", "哈密瓜"] # 在索引1的位置插入 print(fruits) # ['芒果', '西瓜', '哈密瓜', '菠萝', '橙子']列表的查询和统计
numbers = [1, 3, 5, 3, 7, 9, 3, 1] # 获取列表长度 print(len(numbers)) # 8 # 统计元素出现次数 print(numbers.count(3)) # 3 - 数字3出现了3次 print(numbers.count(1)) # 2 - 数字1出现了2次 # 查找元素索引 print(numbers.index(5)) # 2 - 数字5第一次出现的索引 print(numbers.index(3)) # 1 - 数字3第一次出现的索引 print(numbers.index(3, 2)) # 3 - 从索引2开始找数字3 # 检查元素是否存在 print(5 in numbers) # True print(10 in numbers) # False3.2 元组 (Tuple) - 有序的不可变序列
元组就像是一个固定的清单、密封的档案袋或者不可修改的合同,一旦创建就不能修改。适合存放不应该改变的数据。
- 有序:元素有固定位置
- 不可变:创建后不能修改
- 可重复:允许重复元素
- 通常用于存储相关数据:如坐标、配置信息等
# 创建元组 - 一旦创建就不能修改 colors = ("红色", "绿色", "蓝色") coordinates = (10, 20) print(colors[0]) # 红色 - 可以访问 # colors[0] = "黄色" # 错误!元组不能修改 # 元组的用途:保证数据不会被意外修改 student_info = ("张三", 18, "清华大学") name, age, school = student_info # 元组解包 print(f"{name}今年{age}岁,在{school}上学")3.3 字典 (Dict) - 键值对集合
字典就像是一个通讯录或者词典,通过"键"(如名字)快速找到对应的"值"(如电话号码)。
- 键值对:每个元素由键(key)和值(value)组成
- 无序:Python 3.7+ 保持插入顺序,但本质上无序
- 键必须唯一:不能有重复的键
- 键必须是不可变类型:字符串、数字、元组等
- 值可以是任意类型:包括列表、字典等
# 创建字典 - 像通讯录:名字→电话号码 contacts = { "张三": "13800138000", "李四": "13900139000", "王五": "13700137000" } # 访问值 - 通过名字找电话 print(contacts["张三"]) # 13800138000 # 添加或修改 contacts["赵六"] = "13600136000" # 添加新联系人 contacts["张三"] = "13800138001" # 修改已有联系人的电话 # 删除 del contacts["李四"] print(contacts)字典的常用方法
student = {"name": "小明", "age": 18, "score": 95} # 检查键是否存在 print("name" in student) # True - 有name这个键 print("address" in student) # False - 没有address这个键 # 安全获取值(不会报错) print(student.get("name")) # 小明 print(student.get("address")) # None(不会报错) print(student.get("address", "未知")) # 未知(提供默认值) # 获取所有键和值 print(student.keys()) # 所有键:name, age, score print(student.values()) # 所有值:小明, 18, 953.4 集合 (Set) - 无序的唯一元素集合
集合就像是一个没有重复项目的袋子,自动去除重复,而且不关心顺序。
- 无序:元素没有固定顺序
- 唯一:自动去除重复元素
- 可变:可以添加、删除元素
- 只能包含不可变类型:数字、字符串、元组等
# 创建集合 - 自动去重 fruits = {"苹果", "香蕉", "橙子", "苹果"} # 重复的"苹果"会被自动去掉 print(fruits) # {'橙子', '香蕉', '苹果'} - 顺序可能不同 # 集合操作 - 像数学中的集合运算 set1 = {1, 2, 3, 4, 5} set2 = {4, 5, 6, 7, 8} print(set1 | set2) # 并集: {1, 2, 3, 4, 5, 6, 7, 8} - 所有元素 print(set1 & set2) # 交集: {4, 5} - 共同元素 print(set1 - set2) # 差集: {1, 2, 3} - set1有但set2没有 print(set1 ^ set2) # 对称差集: {1, 2, 3, 6, 7, 8} - 不同时属于两个集合的元素4. Python 函数和模块
4.1 函数基础
什么是函数?
函数就像是一个预制工具或者食谱 - 你定义一次制作方法,之后可以多次使用。
- 定义函数 = 设计电器的功能或建立生产线
- 调用函数 = 使用电器或启动生产线
- 参数 = 给电器提供原料或给生产线提供材料
- 返回值 = 电器产出的成品或生产线的最终产品
# 定义函数 - 就像设计一个厨房电器 def make_tea(tea_type, sugar_level=1): """ 泡茶函数 参数: tea_type: 茶叶类型 sugar_level: 糖度级别 (1-5) 返回: 泡好的茶描述 """ tea_description = f"一杯{tea_type}茶" if sugar_level > 1: tea_description += f",糖度{sugar_level}级" return tea_description # 调用函数 - 就像使用电器 tea1 = make_tea("绿茶") # 使用默认糖度 tea2 = make_tea("红茶", 3) # 指定糖度 tea3 = make_tea(sugar_level=5, tea_type="乌龙茶") # 使用关键字参数 print(tea1) # 一杯绿茶茶 print(tea2) # 一杯红茶茶,糖度3级 print(tea3) # 一杯乌龙茶茶,糖度5级函数参数:给工具提供材料
位置参数
def create_student_info(name, age, grade): """创建学生信息 - 参数必须按顺序传递""" return f"姓名:{name},年龄:{age},年级:{grade}" # 必须按顺序传递参数 info1 = create_student_info("小明", 15, "九年级") print(info1) # 姓名:小明,年龄:15,年级:九年级 # 如果顺序错误,结果可能不对 info2 = create_student_info(15, "小明", "九年级") # 错误的顺序 print(info2) # 姓名:15,年龄:小明,年级:九年级默认参数:
def order_coffee(coffee_type, size="中杯", sugar=True, ice=False): """订购咖啡 - 带有默认参数""" order = f"{size}{coffee_type}" if sugar: order += ",加糖" else: order += ",无糖" if ice: order += ",加冰" else: order += ",热饮" return order # 使用不同方式调用 order1 = order_coffee("拿铁") # 使用所有默认值 order2 = order_coffee("美式", "大杯") # 修改部分默认值 order3 = order_coffee("卡布奇诺", sugar=False) # 跳过中间参数 order4 = order_coffee("摩卡", "小杯", True, True) # 全部指定 print(order1) # 中杯拿铁,加糖,热饮 print(order2) # 大杯美式,加糖,热饮 print(order3) # 中杯卡布奇诺,无糖,热饮 print(order4) # 小杯摩卡,加糖,加冰关键字参数:
def build_computer(cpu, memory, storage, gpu="集成显卡", monitor=24): """组装电脑 - 使用关键字参数更清晰""" return f"CPU: {cpu}, 内存: {memory}G, 硬盘: {storage}G, 显卡: {gpu}, 显示器: {monitor}寸" # 使用关键字参数 - 顺序不重要,更清晰 computer1 = build_computer(cpu="i7", memory=16, storage=512) computer2 = build_computer(memory=32, storage=1000, cpu="i9", gpu="RTX 4080") computer3 = build_computer("i5", 8, 256, monitor=27) # 混合使用 print(computer1) # CPU: i7, 内存: 16G, 硬盘: 512G, 显卡: 集成显卡, 显示器: 24寸 print(computer2) # CPU: i9, 内存: 32G, 硬盘: 1000G, 显卡: RTX 4080, 显示器: 24寸 print(computer3) # CPU: i5, 内存: 8G, 硬盘: 256G, 显卡: 集成显卡, 显示器: 27寸可变参数 (*args 和 **kwargs):
def make_smoothie(*fruits, **extras): """制作果汁 - 接受任意数量的水果和额外选项""" smoothie = "混合果汁包含:" smoothie += "、".join(fruits) if extras: smoothie += ",额外添加:" for item, amount in extras.items(): smoothie += f"{item}{amount}份、" smoothie = smoothie.rstrip("、") return smoothie # 使用可变参数 smoothie1 = make_smoothie("香蕉", "草莓") smoothie2 = make_smoothie("芒果", "菠萝", "椰子", ice=2, sugar=1) smoothie3 = make_smoothie("苹果", yogurt=1, honey=1) print(smoothie1) # 混合果汁包含:香蕉、草莓 print(smoothie2) # 混合果汁包含:芒果、菠萝、椰子,额外添加:ice2份、sugar1份 print(smoothie3) # 混合果汁包含:苹果,额外添加:yogurt1份、honey1份返回值:工具给出的结果
# 返回单个值 def calculate_bmi(weight, height): """计算BMI指数""" bmi = weight / (height ** 2) return round(bmi, 2) # 返回多个值(实际上是返回元组) def analyze_scores(scores): """分析成绩数据""" average = sum(scores) / len(scores) highest = max(scores) lowest = min(scores) count = len(scores) return average, highest, lowest, count # 返回元组 # 返回字典(结构化数据) def get_student_report(name, scores): """生成学生报告""" average = sum(scores) / len(scores) grade = "优秀" if average >= 90 else "良好" if average >= 80 else "及格" return { "姓名": name, "平均分": round(average, 2), "最高分": max(scores), "最低分": min(scores), "等级": grade } # 使用函数 bmi = calculate_bmi(70, 1.75) print(f"BMI指数: {bmi}") avg, high, low, cnt = analyze_scores([85, 92, 78, 96, 88]) print(f"平均分: {avg}, 最高分: {high}, 最低分: {low}, 人数: {cnt}") report = get_student_report("小明", [85, 92, 78, 96, 88]) print(f"学生报告: {report}")函数的文档字符串
def calculate_compound_interest(principal, rate, years, compound_frequency=1): """ 计算复利 参数: principal (float): 本金 rate (float): 年利率 (例如 0.05 表示 5%) years (int): 投资年数 compound_frequency (int): 复利计算频率 (1=年, 12=月) 返回: tuple: (最终金额, 总收益) 示例: >>> calculate_compound_interest(1000, 0.05, 10) (1628.89, 628.89) """ # 实际的计算代码 final_amount = principal * (1 + rate/compound_frequency) ** (compound_frequency * years) total_earnings = final_amount - principal return round(final_amount, 2), round(total_earnings, 2) # 查看函数的文档 print(calculate_compound_interest.__doc__) # 使用函数 result = calculate_compound_interest(1000, 0.05, 10) print(f"最终金额: {result[0]}, 总收益: {result[1]}")4.2 变量作用域:变量的可见范围
局部作用域 vs 全局作用域:
# 全局变量 - 在整个程序中可用 school_name = "第一中学" student_count = 0 # 用于统计学生数量 def register_student(name, grade): """注册学生 - 演示局部变量和全局变量""" # 局部变量 - 只在函数内部可用 student_id = f"{grade}_{name}" classroom = f"{grade}班" # 可以访问全局变量 print(f"{name} 在 {school_name} {classroom} 注册") # 如果要修改全局变量,需要使用 global 关键字 global student_count student_count += 1 # 返回局部变量 return student_id, classroom def create_student_profile(name, age): """创建学生档案 - 嵌套函数演示""" # 外层函数的局部变量 profile_id = f"STU{age:03d}" def generate_email(): """内层函数 - 可以访问外层函数的变量""" # 可以访问外层函数的局部变量 email = f"{name}@{school_name}.edu.cn" # 也可以访问全局变量 return email.lower() email = generate_email() return { "id": profile_id, "name": name, "email": email, "school": school_name } # 使用函数 id1, class1 = register_student("小明", "九年级") id2, class2 = register_student("小红", "八年级") print(f"学生ID: {id1}, 班级: {class1}") print(f"学生ID: {id2}, 班级: {class2}") print(f"总共注册了 {student_count} 名学生") profile = create_student_profile("张三", 15) print(f"学生档案: {profile}") # 尝试访问局部变量(会报错) # print(student_id) # ❌ 错误:student_id 是局部变量 # print(profile_id) # ❌ 错误:profile_id 是局部变量nonlocal 关键字:
def counter_factory(): """计数器工厂 - 演示 nonlocal 使用""" count = 0 # 外层函数的局部变量 def increment(): """内层计数器""" nonlocal count # 声明使用外层函数的变量 count += 1 return count def reset(): """重置计数器""" nonlocal count count = 0 return count def get_count(): """获取当前计数""" return count # 返回内层函数 return increment, reset, get_count # 使用计数器 inc, reset, get = counter_factory() print(inc()) # 1 print(inc()) # 2 print(inc()) # 3 print(f"当前计数: {get()}") # 当前计数: 3 reset() print(f"重置后计数: {get()}") # 重置后计数: 04.3 匿名函数 (Lambda):一次性小工具
- 匿名函数(Lambda)
- 概念:匿名函数是一种不需要定义函数名的简单函数,通常用于需要一个函数作为参数的场合,或者只需要使用一次的函数。
- 语法:lambda 参数1, 参数2, ... : 表达式
- 特点:lambda函数只能包含一个表达式,不能包含复杂的语句,但表达式可以很复杂(如三元运算符等)。它的计算结果就是表达式的返回值。
匿名函数就像一次性的便利贴或临时工具:传统函数 = 正规的工具箱(有名称,可重复使用)Lambda函数 = 一次性的便签纸(用完即弃,临时使用)
# 传统函数定义方式 def square(x): return x * x # Lambda函数定义方式 square = lambda x: x * x print(square(5)) # 25 - 两种方式结果相同 # Lambda函数的组成: # lambda : 关键字,表示创建匿名函数 # x : 参数(可以有多个参数) # : : 分隔符,分隔参数和表达式 # x * x : 表达式,自动返回计算结果4.4 模块:工具库
- 概念:模块是一个包含Python代码的文件,它可以包含函数、类、变量等。我们可以将代码按功能组织到不同的模块中,以便于重用和维护。
- 导入方式:有多种导入方式,可以根据需要选择。
模块系统就像乐高积木:模块 = 一盒特定的乐高积木导入模块 = 打开乐高盒子使用函数 = 使用特定的积木块标准库 = 官方提供的乐高套装第三方库 = 其他公司制作的乐高扩展包
Python模块导入的6种方式
python # 方式1:导入整个模块(最常用) import math print(f"√16 = {math.sqrt(16)}") print(f"圆周率π ≈ {math.pi}") # 方式2:导入特定功能(避免命名空间污染) from math import sqrt, pi print(f"√25 = {sqrt(25)}") print(f"圆周率π ≈ {pi}") # 方式3:导入并重命名(避免名称冲突) import math as m from datetime import datetime as dt print(f"√36 = {m.sqrt(36)}") print(f"当前时间: {dt.now()}") # 方式4:导入所有功能(不推荐!容易引起混乱) # from math import * # print(f"sin(90) = {sin(pi/2)}") # 方式5:相对导入(在包内部使用) # from . import module_name # 同一目录下的模块 # from .. import module_name # 上级目录的模块 # 方式6:动态导入(根据条件导入) module_name = "math" math_module = __import__(module_name) print(f"动态导入的sqrt(49) = {math_module.sqrt(49)}")常用内置模块
常用内置模块详解
math模块 - 数学工具箱
python import math print("=== Math模块功能演示 ===") # 1. 基本数学常数 print(f"圆周率π: {math.pi}") print(f"自然常数e: {math.e}") print(f"无穷大: {math.inf}") print(f"非数字: {math.nan}") # 2. 基本数学运算 print(f"\n=== 基本运算 ===") print(f"平方根√64: {math.sqrt(64)}") print(f"绝对值|-5|: {abs(-5)}") # 注意:abs是内置函数,不是math模块的 print(f"阶乘5!: {math.factorial(5)}") print(f"最大公约数gcd(48, 18): {math.gcd(48, 18)}") print(f"最小公倍数lcm(15, 20): {math.lcm(15, 20)}") # Python 3.9+ # 3. 对数函数 print(f"\n=== 对数函数 ===") print(f"自然对数ln(e): {math.log(math.e)}") print(f"以10为底log10(100): {math.log10(100)}") print(f"以2为底log2(8): {math.log2(8)}") # 4. 三角函数(角度用弧度表示) print(f"\n=== 三角函数 ===") angle_degrees = 45 angle_radians = math.radians(angle_degrees) # 角度转弧度 print(f"{angle_degrees}° = {angle_radians:.2f} 弧度") print(f"sin({angle_degrees}°): {math.sin(angle_radians):.2f}") print(f"cos({angle_degrees}°): {math.cos(angle_radians):.2f}") print(f"tan({angle_degrees}°): {math.tan(angle_radians):.2f}") # 5. 幂函数 print(f"\n=== 幂函数 ===") print(f"2的3次方: {math.pow(2, 3)}") print(f"e的2次方: {math.exp(2)}") # 6. 取整函数 print(f"\n=== 取整函数 ===") print(f"向上取整ceil(3.2): {math.ceil(3.2)}") # 4 print(f"向下取整floor(3.8): {math.floor(3.8)}") # 3 print(f"四舍五入round(3.5): {round(3.5)}") # 4 (内置函数) print(f"截断小数trunc(3.8): {math.trunc(3.8)}") # 3 # 7. 角度转换 print(f"\n=== 角度转换 ===") print(f"180°转弧度: {math.radians(180)}") # π print(f"π转角度: {math.degrees(math.pi)}") # 180°random模块 - 随机数生成器
import random import string print("=== Random模块功能演示 ===") # 1. 基本随机数 print(f"\n=== 基本随机 ===") print(f"0-1随机小数: {random.random()}") print(f"1-100随机整数: {random.randint(1, 100)}") print(f"1-10随机整数(步长2): {random.randrange(1, 10, 2)}") # 2. 序列操作 print(f"\n=== 序列操作 ===") fruits = ["苹果", "香蕉", "橙子", "葡萄", "草莓"] print(f"随机选择一个: {random.choice(fruits)}") print(f"随机选择3个(可重复): {random.choices(fruits, k=3)}") print(f"随机选择2个(不重复): {random.sample(fruits, 2)}") # 打乱顺序(原地修改) random.shuffle(fruits) print(f"打乱后的列表: {fruits}") # 3. 随机分布 print(f"\n=== 随机分布 ===") print(f"1.5-4.5均匀分布: {random.uniform(1.5, 4.5):.2f}") print(f"正态分布(均值0,标准差1): {random.gauss(0, 1):.2f}") # 4. 随机字符串 print(f"\n=== 随机字符串 ===") # 随机小写字母.join(random.choices(string.ascii_lowercase, k=8)) print(f"8位随机小写字母: {random_letters}") # 随机数字.join(random.choices(string.digits, k=6)) print(f"6位随机数字: {random_digits}") # 随机密码(字母+数字) password_chars = string.ascii_letters + string.digits + "!@#$%^&*".join(random.choices(password_chars, k=10)) print(f"10位随机密码: {random_password}") # 5. 设置随机种子(确保结果可重现) print(f"\n=== 随机种子 ===") random.seed(42) # 设置种子 print(f"种子42的第一个随机数: {random.random()}") print(f"种子42的第二个随机数: {random.random()}") random.seed(42) # 重新设置相同的种子 print(f"重新设置种子42的第一个随机数: {random.random()}") # 与上面相同datetime模块 - 时间和日期管理
from datetime import datetime, date, time, timedelta import time as time_module # 避免与datetime.time冲突 print("=== Datetime模块功能演示 ===") # 1. 获取当前时间 print(f"\n=== 当前时间 ===") now = datetime.now() today = date.today() current_time = now.time() print(f"当前完整时间: {now}") print(f"当前日期: {today}") print(f"当前时间: {current_time}") print(f"时间戳: {now.timestamp()}") # 1970年1月1日以来的秒数 # 2. 创建特定时间 print(f"\n=== 创建特定时间 ===") birthday = datetime(2000, 5, 15, 14, 30, 0) print(f"生日: {birthday}") print(f"生日年份: {birthday.year}") print(f"生日月份: {birthday.month}") print(f"生日日期: {birthday.day}") print(f"生日小时: {birthday.hour}") print(f"生日分钟: {birthday.minute}") # 3. 时间格式化 print(f"\n=== 时间格式化 ===") print(f"ISO格式: {now.isoformat()}") print(f"自定义格式: {now.strftime('%Y年%m月%d日 %H时%M分%S秒')}") print(f"星期几(0=周一): {now.weekday()}") print(f"星期几(英文): {now.strftime('%A')}") print(f"月份(英文): {now.strftime('%B')}") # 4. 时间计算 print(f"\n=== 时间计算 ===") print(f"现在: {now}") one_day = timedelta(days=1) one_hour = timedelta(hours=1) one_week = timedelta(weeks=1) print(f"明天: {now + one_day}") print(f"昨天: {now - one_day}") print(f"一小时后: {now + one_hour}") print(f"一周后: {now + one_week}") # 5. 时间差 print(f"\n=== 时间差 ===") start_time = datetime(2024, 1, 1, 8, 0, 0) end_time = datetime(2024, 1, 1, 17, 30, 0) time_difference = end_time - start_time print(f"开始时间: {start_time}") print(f"结束时间: {end_time}") print(f"时间差: {time_difference}") print(f"总秒数: {time_difference.total_seconds()}") print(f"天数: {time_difference.days}") print(f"秒数(除去天数): {time_difference.seconds}") # 6. 时间休眠 print(f"\n=== 时间休眠 ===") print("开始等待2秒...") time_module.sleep(2) # 程序暂停2秒 print("等待结束!") # 7. 计算程序运行时间 print(f"\n=== 程序运行时间 ===") start = time_module.time() # 获取当前时间戳 # 模拟一些工作 total = 0 for i in range(1000000): total += i end = time_module.time() print(f"计算完成,用时: {end - start:.4f} 秒")os模块 - 操作系统接口
import os import sys print("=== OS模块功能演示 ===") # 1. 文件和目录操作 print(f"\n=== 文件和目录 ===") print(f"当前工作目录: {os.getcwd()}") print(f"当前用户: {os.getlogin()}") print(f"当前进程ID: {os.getpid()}") # 列出目录内容 print(f"\n当前目录内容:") for item in os.listdir('.'): # 判断是文件还是目录 if os.path.isfile(item): type_label = "文件" elif os.path.isdir(item): type_label = "目录" else: type_label = "其他" # 获取文件大小 if os.path.isfile(item): size = os.path.getsize(item) print(f" {item} ({type_label}, {size}字节)") else: print(f" {item} ({type_label})") # 2. 路径操作 print(f"\n=== 路径操作 ===") file_path = "/home/user/documents/report.txt" print(f"完整路径: {file_path}") print(f"目录名: {os.path.dirname(file_path)}") print(f"文件名: {os.path.basename(file_path)}") print(f"分割路径: {os.path.split(file_path)}") print(f"分割扩展名: {os.path.splitext(file_path)}") # 构建路径(跨平台) new_path = os.path.join("documents", "reports", "annual.pdf") print(f"构建的路径: {new_path}") # 3. 文件属性检查 print(f"\n=== 文件属性 ===") test_file = "example.txt" # 创建测试文件 with open(test_file, 'w') as f: f.write("这是一个测试文件") print(f"文件存在: {os.path.exists(test_file)}") print(f"是文件: {os.path.isfile(test_file)}") print(f"是目录: {os.path.isdir(test_file)}") print(f"文件大小: {os.path.getsize(test_file)} 字节") print(f"最后修改时间: {os.path.getmtime(test_file)}") print(f"最后访问时间: {os.path.getatime(test_file)}") # 4. 环境变量 print(f"\n=== 环境变量 ===") print(f"PATH: {os.getenv('PATH', '未设置')}") print(f"HOME: {os.getenv('HOME', '未设置')}") print(f"USER: {os.getenv('USER', '未设置')}") print(f"PYTHONPATH: {os.getenv('PYTHONPATH', '未设置')}") # 5. 系统信息 print(f"\n=== 系统信息 ===") print(f"操作系统类型: {os.name}") print(f"路径分隔符: {repr(os.sep)}") print(f"换行符: {repr(os.linesep)}") # 6. 进程管理 print(f"\n=== 进程管理 ===") print(f"命令行参数: {sys.argv}") print(f"Python版本: {sys.version}") # 7. 执行系统命令 print(f"\n=== 系统命令 ===") # 注意:执行系统命令可能有安全风险,请谨慎使用 if os.name == 'nt': # Windows os.system('echo Hello from Windows') else: # Linux/Mac os.system('echo "Hello from Unix-like system"') # 清理测试文件 os.remove(test_file) print(f"\n已删除测试文件: {test_file}")5. Python 面向对象编程 (OOP)
5.1 类与对象的基本概念
什么是类和对象?
- 类:就像设计图纸,定义了对象的蓝图
- 对象:就像根据图纸制造的具体产品
python class Student: """学生类 - 就像学生这个概念的蓝图""" def __init__(self, name, age, score): # 初始化方法 - 创建对象时自动调用,像产品出厂设置 self.name = name # 属性:姓名 self.age = age # 属性:年龄 self.score = score # 属性:分数 def introduce(self): """方法:自我介绍""" return f"我叫{self.name},今年{self.age}岁" def study(self, hours): """方法:学习""" self.score += hours * 0.5 return f"学习了{hours}小时,分数提升了{hours * 0.5}" # 创建对象(实例化) - 根据蓝图制造具体产品 student1 = Student("小明", 18, 85) student2 = Student("小红", 17, 92) # 使用对象 print(student1.introduce()) # 我叫小明,今年18岁 print(student2.study(2)) # 学习了2小时,分数提升了1.0 print(f"{student2.name}的分数:{student2.score}") # 小红的分数:93.05.2 封装:保护内部数据
封装就像把东西放进保险箱 - 内部细节被保护,只通过特定接口访问。
python class BankAccount: def __init__(self, initial_balance=0): self.__balance = initial_balance # 私有属性,外部不能直接访问 def deposit(self, amount): """存款 - 只能通过这个方法存钱""" if amount > 0: self.__balance += amount return f"存款成功,当前余额:{self.__balance}" else: return "存款金额必须大于0" def withdraw(self, amount): """取款 - 只能通过这个方法取钱""" if amount > self.__balance: return "余额不足" elif amount <= 0: return "取款金额必须大于0" else: self.__balance -= amount return f"取款成功,当前余额:{self.__balance}" def get_balance(self): """查看余额 - 只能通过这个方法看余额""" return self.__balance # 使用银行账户 account = BankAccount(1000) print(account.deposit(500)) # 存款成功,当前余额:1500 print(account.withdraw(200)) # 取款成功,当前余额:1300 print(account.get_balance()) # 1300 # print(account.__balance) # 错误!不能直接访问私有属性5.3 继承:家族传承
继承就像家族传承 - 子类继承父类的特征,还可以有自己的特色。
python class Animal: """动物基类 - 所有动物的共同特征""" def __init__(self, name): self.name = name def speak(self): return "动物发出声音" def eat(self): return f"{self.name}在吃东西" class Dog(Animal): # Dog类继承Animal类 """狗类 - 继承自动物,还有狗的特色""" def speak(self): # 重写父类方法 - 狗有自己的叫声 return "汪汪!" def fetch(self): # 子类特有的方法 - 只有狗会接飞盘 return f"{self.name}在接飞盘" class Cat(Animal): # Cat类继承Animal类 """猫类 - 继承自动物,还有猫的特色""" def speak(self): # 重写父类方法 - 猫有自己的叫声 return "喵喵!" def climb(self): # 子类特有的方法 - 只有猫会爬树 return f"{self.name}在爬树" # 使用继承的类 dog = Dog("旺财") cat = Cat("咪咪") print(dog.speak()) # 汪汪! print(cat.speak()) # 喵喵! print(dog.eat()) # 旺财在吃东西(继承自父类) print(dog.fetch()) # 旺财在接飞盘(子类特有)5.4 多态:同一指令,不同反应
多态就像同一指令,不同反应 - 不同对象对同一方法有不同的实现。
python class Shape: """形状基类""" def area(self): pass class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): return 3.14 * self.radius ** 2 class Rectangle(Shape): def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height class Triangle(Shape): def __init__(self, base, height): self.base = base self.height = height def area(self): return 0.5 * self.base * self.height # 多态的应用:对不同对象执行相同操作,得到不同结果 shapes = [Circle(5), Rectangle(4, 6), Triangle(3, 4)] for shape in shapes: print(f"形状面积:{shape.area():.2f}") # 输出: # 形状面积:78.50(圆) # 形状面积:24.00(矩形) # 形状面积:6.00(三角形)学习建议
如何学好Python?
- 理解概念比死记硬背更重要
- 把编程概念与现实生活联系起来
- 多用比喻理解抽象概念
- 多动手实践
- 每个例子都要自己敲一遍
- 尝试修改例子看看会发生什么
- 从简单到复杂
- 先掌握基础语法
- 再学习数据结构和函数
- 最后学习面向对象和高级特性
- 不要怕犯错
- 错误信息是学习的最好机会
- 通过调试理解程序运行原理
下一步学习路径
- 巩固基础:反复练习变量、条件、循环
- 项目实践:尝试写一些小程序,如计算器、猜数字游戏
- 学习高级主题:文件操作、异常处理、网络编程
- 专业方向:Web开发、数据分析、人工智能等
记住,编程就像学骑自行车 - 开始可能会摔倒,但一旦掌握了,就会变得自然而然!