Python 语法大全 + 实战详解
🐍 Python 语法大全 + 实战详解
从零基础到实战应用,一份系统完整的Python学习指南
📚 第一部分:Python 基础语法
1.1 代码结构与规范
缩进规则 —— Python的独特之处
与C、Java等使用大括号不同,Python使用缩进来定义代码块。
# ✅ 正确写法
def do_something(i):
if i > 0:
print("Positive value:", i)
i += 1
else:
print("Negative or zero")
# ❌ 错误写法 —— 缩进不一致会报错
def do_something(i):
if i > 0:
print("Positive")
i += 1 # 缩进错误!IndentationError
最佳实践:
· 官方推荐使用4个空格缩进
· 不要混用制表符和空格——Python 3中会直接报语法错误
· 同一代码块内的缩进必须一致
注释
# 这是单行注释
"""
这是多行注释
可以写多行内容
通常用于函数/类的文档说明
"""
def greet(name):
"""这是文档字符串,用于函数说明"""
return f"Hello, {name}"
编码声明
# -*- coding: utf-8 -*-
# 或
# coding: utf-8
Python 3默认UTF-8编码,一般无需显式声明。
1.2 变量与数据类型
变量声明 —— 动态类型
Python是动态类型语言,变量无需声明类型,直接赋值即可。
# 直接赋值,无需声明类型
name = "Alice" # 字符串
age = 25 # 整数
price = 19.99 # 浮点数
is_student = True # 布尔值
核心数据类型
类型 示例 说明
int 42, -7, 0x2A 整数(任意精度)
float 3.14, -0.5, 2.5e-3 浮点数
bool True, False 布尔值
str “Hello”, ‘Python’ 字符串
list [1, 2, 3] 列表(可变序列)
tuple (1, 2, 3) 元组(不可变序列)
dict {“name”: “Alice”} 字典(键值对)
set {1, 2, 3} 集合(无序不重复)
NoneType None 空值
类型转换
# 常用类型转换
int("123") # 123,字符串转整数
float("3.14") # 3.14,转浮点数
str(123) # "123",转字符串
list((1,2,3)) # [1,2,3],元组转列表
1.3 输入与输出
# 输出
print("Hello, World!")
print(f"变量值: {age}") # f-string格式化(Python 3.6+推荐)
print("年龄: %d" % age) # %格式化(类似C的printf)
print("姓名: {}, 年龄: {}".format(name, age)) # format方法
# 输入
name = input("请输入你的名字: ") # 返回字符串
age = int(input("请输入年龄: ")) # 需要手动转换类型
f-string示例:
name = "Bob"
score = 95.5
print(f"{name} 的分数是 {score:.1f} 分") # Bob 的分数是 95.5 分
1.4 运算符
算术运算符
a, b = 10, 3
print(a + b) # 13 加法
print(a - b) # 7 减法
print(a * b) # 30 乘法
print(a / b) # 3.333333... 除法(返回浮点数)
print(a // b) # 3 整除(向下取整)
print(a % b) # 1 取余/取模
print(a ** b) # 1000 幂运算
比较(关系)运算符
x, y = 5, 10
print(x == y) # False 相等
print(x != y) # True 不等
print(x > y) # False 大于
print(x < y) # True 小于
print(x >= 5) # True 大于等于
print(x <= 5) # True 小于等于
逻辑运算符
a, b = True, False
print(a and b) # False 与:两者都真才真
print(a or b) # True 或:至少一个真
print(not a) # False 非:取反
# 短路求值示例
def is_valid(value):
return value is not None and value > 0 # 第一个条件假则不执行第二个
赋值运算符
x = 5
x += 3 # x = x + 3 → 8
x -= 2 # x = x - 2 → 6
x *= 2 # x = x * 2 → 12
x /= 3 # x = x / 3 → 4.0
成员运算符
fruits = ["apple", "banana", "cherry"]
print("apple" in fruits) # True
print("grape" not in fruits) # True
name = "Python"
print("Py" in name) # True
身份运算符
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a is c) # True 同一对象
print(a is b) # False 不同对象(值相同但内存地址不同)
print(a == b) # True 值相等
运算符优先级(从高到低)
- ** 幂运算
- +x, -x, ~x 正负号、按位取反
- *, /, //, % 乘除取余
- +, - 加减
- <<, >> 移位
- & 按位与
- ^ 按位异或
- | 按位或
- in, is, 比较运算符
- not 逻辑非
- and 逻辑与
- or 逻辑或
# 使用括号明确优先级
result = (a + b) * c # 清晰易读
1.5 控制流程
条件判断:if-elif-else
score = 85
if score >= 90:
print("A级")
elif score >= 80:
print("B级")
elif score >= 70:
print("C级")
else:
print("需要努力")
# 输出: B级
嵌套条件:
age = 20
is_student = True
if age < 18:
print("未成年人票")
else:
if is_student:
print("学生票")
else:
print("成人票")
循环语句
for 循环 —— 遍历可迭代对象
# 遍历列表
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# 使用 range() 生成数字序列
for i in range(5): # 0,1,2,3,4
print(i)
for i in range(2, 8): # 2,3,4,5,6,7
print(i)
for i in range(0, 10, 2): # 0,2,4,6,8(步长2)
print(i)
# 遍历字符串
for char in "Python":
print(char)
# 同时获取索引和值
colors = ["red", "green", "blue"]
for index, color in enumerate(colors):
print(f"{index}: {color}")
while 循环
# 基本用法
count = 0
while count < 5:
print(f"计数: {count}")
count += 1
# 无限循环 + break
while True:
user_input = input("输入exit退出: ")
if user_input == "exit":
break
print(f"你输入了: {user_input}")
循环控制语句
# break —— 跳出整个循环
for i in range(10):
if i == 5:
break
print(i) # 输出 0,1,2,3,4
# continue —— 跳过本次循环
for i in range(10):
if i % 2 == 0:
continue
print(i) # 输出 1,3,5,7,9
# else —— 循环正常结束(没有被break)时执行
for i in range(3):
print(i)
else:
print("循环正常结束") # 会执行
for i in range(5):
if i == 3:
break
print(i)
else:
print("不会执行,因为break了")
match-case(Python 3.10+)
def check_status(code):
match code:
case 200:
return "成功"
case 404:
return "未找到"
case 500:
return "服务器错误"
case _: # 默认情况
return "未知状态码"
🗂️ 第二部分:核心数据结构
2.1 列表(List)—— 可变序列
列表是Python最常用的数据结构,使用方括号[]定义。
# 创建列表
empty_list = []
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]
nested = [[1, 2], [3, 4]] # 嵌套列表
# 访问元素(索引从0开始)
fruits = ["apple", "banana", "cherry", "orange"]
print(fruits[0]) # apple
print(fruits[-1]) # orange(负数索引从末尾开始)
print(fruits[1:3]) # ['banana', 'cherry'](切片)
# 修改元素
fruits[1] = "blueberry"
print(fruits) # ['apple', 'blueberry', 'cherry', 'orange']
# 常用方法
fruits.append("grape") # 末尾添加
fruits.insert(1, "mango") # 指定位置插入
fruits.remove("cherry") # 删除指定值
popped = fruits.pop() # 删除并返回末尾元素
fruits.pop(1) # 删除并返回索引1的元素
fruits.sort() # 排序
fruits.reverse() # 反转
fruits.clear() # 清空列表
# 列表长度
print(len(fruits))
# 列表拼接
list1 = [1, 2]
list2 = [3, 4]
combined = list1 + list2 # [1, 2, 3, 4]
list1.extend(list2) # list1变为[1, 2, 3, 4]
# 列表推导式(简洁创建列表)
squares = [x**2 for x in range(1, 6)] # [1, 4, 9, 16, 25]
evens = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
2.2 元组(Tuple)—— 不可变序列
元组使用小括号()定义,创建后不可修改。
# 创建元组
empty_tuple = ()
point = (10, 20)
single = (5,) # 单元素元组必须有逗号
without_parentheses = 1, 2, 3 # 也是元组
# 访问元素
coordinates = (10, 20, 30)
print(coordinates[0]) # 10
print(coordinates[-1]) # 30
# 元组解包
x, y, z = coordinates # x=10, y=20, z=30
# 元组不可修改
# coordinates[0] = 100 # ❌ TypeError
# 元组 vs 列表:元组更节省内存,适合不变的数据
days_of_week = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
2.3 字典(Dict)—— 键值对
字典使用花括号{}定义,存储键值对。
# 创建字典
empty_dict = {}
person = {
"name": "Alice",
"age": 25,
"city": "Beijing"
}
# 使用 dict() 函数
person2 = dict(name="Bob", age=30, city="Shanghai")
# 访问值
print(person["name"]) # Alice
print(person.get("age")) # 25(推荐,键不存在时返回None而非报错)
print(person.get("gender", "Unknown")) # 指定默认值
# 添加/修改
person["age"] = 26 # 修改
person["gender"] = "F" # 添加新键
# 删除
del person["city"]
age = person.pop("age") # 删除并返回值
person.clear() # 清空
# 遍历字典
for key in person:
print(key, person[key])
for key, value in person.items():
print(f"{key}: {value}")
for key in person.keys():
print(key)
for value in person.values():
print(value)
# 字典推导式
squares_dict = {x: x**2 for x in range(5)} # {0:0, 1:1, 2:4, 3:9, 4:16}
2.4 集合(Set)—— 无序不重复
# 创建集合
empty_set = set() # {}是空字典,不是空集合
numbers = {1, 2, 3, 3, 4} # {1, 2, 3, 4}(自动去重)
from_list = set([1, 2, 2, 3]) # {1, 2, 3}
# 添加/删除
numbers.add(5)
numbers.remove(3) # 不存在会报错
numbers.discard(10) # 不存在不会报错
popped = numbers.pop() # 随机删除一个元素
# 集合运算
A = {1, 2, 3, 4}
B = {3, 4, 5, 6}
print(A | B) # 并集: {1,2,3,4,5,6}
print(A & B) # 交集: {3,4}
print(A - B) # 差集: {1,2}
print(A ^ B) # 对称差: {1,2,5,6}
# 判断子集/超集
print({1,2}.issubset(A)) # True
print(A.issuperset({1,2})) # True
2.5 切片操作
切片是Python的强大特性,适用于列表、元组、字符串。
# 语法: [start:end:step]
# start: 起始索引(包含),默认0
# end: 结束索引(不包含),默认len
# step: 步长,默认1
s = "Hello, World!"
print(s[0:5]) # Hello
print(s[:5]) # Hello(省略start)
print(s[7:]) # World!(省略end)
print(s[::2]) # Hlo ol!(每隔一个取一个)
print(s[::-1]) # !dlroW ,olleH(反转)
# 列表切片返回新列表
numbers = [0, 1, 2, 3, 4, 5]
copy = numbers[:] # 完整复制
reverse = numbers[::-1] # 反转
🔧 第三部分:函数
3.1 函数定义与调用
# 基本定义
def greet(name):
"""简单的问候函数"""
return f"Hello, {name}!"
# 调用
message = greet("Alice")
print(message) # Hello, Alice!
# 无返回值(返回None)
def say_hello():
print("Hello!")
result = say_hello() # result为None
3.2 参数类型
# 1. 位置参数(必需参数)
def add(a, b):
return a + b
add(3, 5) # 8
# 2. 默认参数
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
print(greet("Bob")) # Hello, Bob!
print(greet("Bob", "Hi")) # Hi, Bob!
# ⚠️ 默认参数陷阱:不要使用可变对象作为默认值
def bad_append(item, lst=[]): # ❌ 危险!列表会累积
lst.append(item)
return lst
def good_append(item, lst=None): # ✅ 正确做法
if lst is None:
lst = []
lst.append(item)
return lst
# 3. 关键字参数
def person_info(name, age, city):
print(f"{name}, {age}, {city}")
person_info(city="Beijing", name="Alice", age=25) # 顺序可调换
# 4. 可变参数 *args(接收任意多个位置参数)
def sum_all(*args):
return sum(args)
print(sum_all(1, 2, 3, 4)) # 10
# 5. 关键字参数 **kwargs(接收任意多个关键字参数)
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25, city="Beijing")
# 6. 参数组合(顺序:位置参数 > *args > 默认参数 > **kwargs)
def complex_func(a, b, *args, c=10, **kwargs):
pass
3.3 返回值
# 单个返回值
def square(x):
return x ** 2
# 多个返回值(实际返回一个元组)
def get_min_max(numbers):
return min(numbers), max(numbers)
minimum, maximum = get_min_max([3, 1, 4, 1, 5])
print(minimum, maximum) # 1 5
# 提前返回
def check_age(age):
if age < 0:
return "无效年龄"
if age < 18:
return "未成年"
return "成年"
3.4 作用域
# 局部变量 vs 全局变量
global_var = 10 # 全局变量
def my_function():
local_var = 20 # 局部变量
print(global_var) # 可以访问全局变量
def modify_global():
global global_var # 声明要修改全局变量
global_var = 100
# 嵌套函数中的 nonlocal
def outer():
x = 10
def inner():
nonlocal x # 修改外层函数的变量
x = 20
inner()
print(x) # 20
3.5 匿名函数(lambda)
# 基本语法:lambda 参数: 表达式
square = lambda x: x ** 2
print(square(5)) # 25
# 常用于排序和过滤
students = [("Alice", 85), ("Bob", 92), ("Charlie", 78)]
students.sort(key=lambda x: x[1]) # 按分数排序
print(students) # [('Charlie', 78), ('Alice', 85), ('Bob', 92)]
# 配合 filter()
numbers = [1, 2, 3, 4, 5, 6]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4, 6]
# 配合 map()
squared = list(map(lambda x: x ** 2, numbers))
print(squared) # [1, 4, 9, 16, 25, 36]
3.6 装饰器
装饰器是在不修改原函数代码的情况下添加功能的强大工具。
# 基本装饰器
def timer(func):
import time
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 执行时间: {end - start:.4f}秒")
return result
return wrapper
@timer
def slow_function():
import time
time.sleep(1)
print("函数执行完毕")
slow_function()
# 输出:
# 函数执行完毕
# slow_function 执行时间: 1.0002秒
# 带参数的装饰器
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello!")
say_hello() # 打印3次 Hello!
3.7 生成器函数
使用yield关键字,函数返回生成器,惰性求值。
# 生成器函数
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
# 使用生成器
for num in fibonacci(10):
print(num, end=" ") # 0 1 1 2 3 5 8 13 21 34
# 生成器表达式(类似列表推导式但用小括号)
squares_gen = (x**2 for x in range(1000000)) # 不立即计算,节省内存
🏗️ 第四部分:面向对象编程
4.1 类与对象
class Dog:
"""狗类"""
# 类属性(所有实例共享)
species = "Canis familiaris"
# 构造方法
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age
# 实例方法
def bark(self):
return f"{self.name} says Woof!"
def get_info(self):
return f"{self.name} is {self.age} years old"
# 字符串表示(类似Java的toString)
def __str__(self):
return f"Dog(name={self.name}, age={self.age})"
# 创建对象
my_dog = Dog("Buddy", 3)
print(my_dog.bark()) # Buddy says Woof!
print(my_dog) # Dog(name=Buddy, age=3)
print(my_dog.species) # Canis familiaris
4.2 继承
# 父类
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("子类必须实现此方法")
def move(self):
return f"{self.name} is moving"
# 子类继承
class Cat(Animal):
def __init__(self, name, color):
super().__init__(name) # 调用父类构造方法
self.color = color
def speak(self):
return f"{self.name} says Meow!"
def purr(self):
return f"{self.name} is purring"
class Bird(Animal):
def speak(self):
return f"{self.name} says Chirp!"
def fly(self):
return f"{self.name} is flying"
# 使用
cat = Cat("Whiskers", "orange")
print(cat.speak()) # Whiskers says Meow!
print(cat.move()) # Whiskers is moving
print(cat.purr()) # Whiskers is purring
bird = Bird("Tweety")
print(bird.speak()) # Tweety says Chirp!
print(bird.fly()) # Tweety is flying
4.3 多态
def animal_sound(animal):
print(animal.speak())
animals = [Cat("Fluffy", "white"), Bird("Polly")]
for animal in animals:
animal_sound(animal)
# 输出:
# Fluffy says Meow!
# Polly says Chirp!
4.4 封装与属性
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self._balance = balance # 单下划线:约定为"保护"成员
self.__secret = "secret" # 双下划线:名称修饰,避免子类覆盖
# property装饰器:将方法当作属性访问
@property
def balance(self):
"""只读属性"""
return self._balance
@balance.setter
def balance(self, value):
"""带验证的设置器"""
if value < 0:
raise ValueError("余额不能为负数")
self._balance = value
def deposit(self, amount):
if amount > 0:
self._balance += amount
def withdraw(self, amount):
if 0 < amount <= self._balance:
self._balance -= amount
return True
return False
# 使用
account = BankAccount("Alice", 1000)
print(account.balance) # 1000(像属性一样访问)
account.deposit(500)
print(account.balance) # 1500
account.balance = 2000 # 使用setter
print(account.balance) # 2000
❌ 第五部分:异常处理
5.1 try-except 基础
# 基本用法
try:
num = int(input("请输入数字: "))
result = 10 / num
print(f"结果: {result}")
except ValueError:
print("错误:请输入有效的数字")
except ZeroDivisionError:
print("错误:除数不能为零")
except Exception as e:
print(f"未知错误: {e}")
5.2 try-except-else-finally
def safe_divide(a, b):
try:
result = a / b
except ZeroDivisionError:
print("除数不能为零")
return None
except TypeError:
print("参数类型错误")
return None
else:
# 没有异常时执行
print("除法运算成功")
return result
finally:
# 无论是否异常都会执行
print("除法运算结束")
print(safe_divide(10, 2))
# 输出:
# 除法运算成功
# 除法运算结束
# 5.0
print(safe_divide(10, 0))
# 输出:
# 除数不能为零
# 除法运算结束
# None
5.3 自定义异常
class InsufficientFundsError(Exception):
"""账户余额不足异常"""
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(f"余额不足: 当前余额{balance}, 需要{amount}")
class BankAccount:
def __init__(self, balance=0):
self.balance = balance
def withdraw(self, amount):
if amount > self.balance:
raise InsufficientFundsError(self.balance, amount)
self.balance -= amount
# 使用自定义异常
account = BankAccount(100)
try:
account.withdraw(200)
except InsufficientFundsError as e:
print(e) # 余额不足: 当前余额100, 需要200
📁 第六部分:文件与目录操作
6.1 文件读写
# 写入文件
with open("test.txt", "w", encoding="utf-8") as file:
file.write("Hello, World!\n")
file.write("第二行内容")
# 读取整个文件
with open("test.txt", "r", encoding="utf-8") as file:
content = file.read()
print(content)
# 逐行读取
with open("test.txt", "r", encoding="utf-8") as file:
for line in file:
print(line.strip()) # strip()去除换行符
# 读取所有行到列表
with open("test.txt", "r", encoding="utf-8") as file:
lines = file.readlines()
print(lines)
# 追加内容
with open("test.txt", "a", encoding="utf-8") as file:
file.write("\n追加的内容")
# 二进制文件(图片等)
with open("image.jpg", "rb") as file:
data = file.read()
6.2 文件模式说明
模式 说明
‘r’ 只读(默认)
‘w’ 写入(覆盖已有内容)
‘a’ 追加(末尾添加)
‘x’ 独占创建(文件存在则报错)
‘b’ 二进制模式(如’rb’)
‘+’ 读写模式(如’r+')
6.3 目录操作(os模块)
import os
import shutil
# 当前工作目录
current_dir = os.getcwd()
print(current_dir)
# 列出目录内容
files = os.listdir(".")
print(files)
# 创建目录
os.mkdir("new_folder")
os.makedirs("parent/child/grandchild") # 创建多级目录
# 删除目录
os.rmdir("empty_folder") # 只能删除空目录
shutil.rmtree("non_empty_folder") # 删除非空目录
# 重命名/移动
os.rename("old_name.txt", "new_name.txt")
# 检查路径是否存在
if os.path.exists("test.txt"):
print("文件存在")
# 判断是文件还是目录
print(os.path.isfile("test.txt")) # True
print(os.path.isdir("new_folder")) # True
# 路径拼接(跨平台)
path = os.path.join("folder", "subfolder", "file.txt")
print(path) # folder/subfolder/file.txt
# 获取文件大小和修改时间
size = os.path.getsize("test.txt")
mtime = os.path.getmtime("test.txt")
6.4 使用 pathlib(现代推荐)
from pathlib import Path
# 创建路径对象
path = Path("documents/notes.txt")
# 读写文件
path.write_text("Hello, World!", encoding="utf-8")
content = path.read_text(encoding="utf-8")
# 路径操作
print(path.name) # notes.txt
print(path.stem) # notes
print(path.suffix) # .txt
print(path.parent) # documents
# 遍历目录
for file in Path(".").glob("*.py"):
print(file)
# 递归查找
for file in Path(".").rglob("*.txt"):
print(file)
📦 第七部分:模块与包
7.1 导入模块
# 导入整个模块
import math
print(math.sqrt(16)) # 4.0
# 导入并重命名
import numpy as np
arr = np.array([1, 2, 3])
# 从模块导入特定函数
from datetime import datetime, timedelta
now = datetime.now()
tomorrow = now + timedelta(days=1)
# 导入所有(不推荐)
from os import *
# 动态导入
import importlib
math = importlib.import_module("math")
7.2 常用内置模块
# random - 随机数
import random
print(random.random()) # 0-1随机浮点数
print(random.randint(1, 10)) # 1-10随机整数
print(random.choice(["a", "b", "c"])) # 随机选择
# datetime - 日期时间
from datetime import datetime, date, time
now = datetime.now()
print(now.year, now.month, now.day)
print(now.strftime("%Y-%m-%d %H:%M:%S"))
# json - JSON处理
import json
data = {"name": "Alice", "age": 25}
json_str = json.dumps(data) # 转JSON字符串
parsed = json.loads(json_str) # 解析JSON字符串
# re - 正则表达式
import re
pattern = r"\d+" # 匹配数字
result = re.findall(pattern, "I have 10 apples and 3 oranges")
print(result) # ['10', '3']
# collections - 高级容器
from collections import defaultdict, Counter, deque
# defaultdict:带默认值的字典
dd = defaultdict(int)
dd["count"] += 1 # 不需要检查键是否存在
# Counter:计数器
c = Counter("hello world")
print(c) # Counter({'l': 3, 'o': 2, ...})
# deque:双端队列
dq = deque([1, 2, 3])
dq.appendleft(0)
dq.append(4)
7.3 创建自定义模块
# mymodule.py
"""
我的自定义模块
"""
__version__ = "1.0.0"
def add(a, b):
return a + b
def multiply(a, b):
return a * b
class Calculator:
def __init__(self):
self.result = 0
def add(self, x):
self.result += x
return self.result
# 防止被导入时执行
if __name__ == "__main__":
# 仅在直接运行此脚本时执行
print("Testing module...")
print(add(3, 5))
# 使用自定义模块
import mymodule
from mymodule import Calculator, __version__
print(__version__) # 1.0.0
calc = Calculator()
print(calc.add(10)) # 10
🚀 第八部分:实战项目
8.1 项目一:天气查询命令行工具
技术栈:requests、argparse、JSON处理、异常处理
#!/usr/bin/env python3
"""
天气查询命令行工具
使用 Open-Meteo 免费API(无需API Key)
"""
import requests
import argparse
import json
from datetime import datetime
# 城市坐标数据库(简化版,实际可用geopy库)
CITY_COORDS = {
"beijing": (39.9042, 116.4074),
"shanghai": (31.2304, 121.4737),
"guangzhou": (23.1291, 113.2644),
"shenzhen": (22.5431, 114.0579),
"hangzhou": (30.2741, 120.1551),
}
def get_weather(lat, lon):
"""获取天气数据"""
url = "https://api.open-meteo.com/v1/forecast"
params = {
"latitude": lat,
"longitude": lon,
"current_weather": True,
"hourly": "temperature_2m,relative_humidity_2m",
"timezone": "Asia/Shanghai"
}
try:
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
print(f"网络请求失败: {e}")
return None
except json.JSONDecodeError as e:
print(f"数据解析失败: {e}")
return None
def display_weather(city, weather_data):
"""显示天气信息"""
if not weather_data or "current_weather" not in weather_data:
print("无法获取天气数据")
return
current = weather_data["current_weather"]
print(f"\n{'='*40}")
print(f"📍 {city.capitalize()} 天气信息")
print(f"{'='*40}")
print(f"🌡️ 温度: {current['temperature']}°C")
print(f"💨 风速: {current['windspeed']} km/h")
print(f"🧭 风向: {current['winddirection']}°")
print(f"📅 更新时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"{'='*40}\n")
def main():
parser = argparse.ArgumentParser(description="天气查询命令行工具")
parser.add_argument("city", help="城市名称(如: beijing, shanghai)")
parser.add_argument("--all", action="store_true", help="显示详细信息")
args = parser.parse_args()
city = args.city.lower()
if city not in CITY_COORDS:
print(f"不支持的城市: {city}")
print(f"支持的城市: {', '.join(CITY_COORDS.keys())}")
return
lat, lon = CITY_COORDS[city]
weather_data = get_weather(lat, lon)
display_weather(city, weather_data)
if __name__ == "__main__":
main()
8.2 项目二:电影数据分析(爬虫 + pandas)
技术栈:requests、BeautifulSoup、pandas、数据可视化
"""
豆瓣电影Top250爬虫与分析
"""
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import re
def fetch_movie_page(start):
"""获取一页电影数据"""
url = f"https://movie.douban.com/top250?start={start}"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
return response.text
except requests.RequestException as e:
print(f"请求失败: {e}")
return None
def parse_movies(html):
"""解析HTML提取电影信息"""
soup = BeautifulSoup(html, "html.parser")
movies = []
for item in soup.select(".item"):
# 标题
title_elem = item.select_one(".title")
title = title_elem.text if title_elem else "N/A"
# 评分
rating_elem = item.select_one(".rating_num")
rating = float(rating_elem.text) if rating_elem else 0
# 年份
info_elem = item.select_one(".bd p")
if info_elem:
info_text = info_elem.text
year_match = re.search(r"(\d{4})", info_text)
year = year_match.group(1) if year_match else "N/A"
else:
year = "N/A"
# 评语
quote_elem = item.select_one(".inq")
quote = quote_elem.text if quote_elem else ""
movies.append({
"title": title,
"rating": rating,
"year": year,
"quote": quote
})
return movies
def collect_all_movies():
"""爬取所有电影"""
all_movies = []
for start in range(0, 250, 25):
print(f"正在爬取第 {start//25 + 1} 页...")
html = fetch_movie_page(start)
if html:
movies = parse_movies(html)
all_movies.extend(movies)
time.sleep(1) # 礼貌延迟
return all_movies
def analyze_movies(df):
"""数据分析"""
print("\n" + "="*50)
print("📊 数据分析报告")
print("="*50)
print(f"\n📝 总电影数量: {len(df)}")
print(f"⭐ 平均评分: {df['rating'].mean():.2f}")
print(f"🏆 最高评分: {df['rating'].max()}")
print(f"📉 最低评分: {df['rating'].min()}")
print("\n🏆 Top 10 高分电影:")
top10 = df.nlargest(10, "rating")[["title", "rating"]]
for i, (_, row) in enumerate(top10.iterrows(), 1):
print(f" {i}. {row['title']} - {row['rating']}")
print("\n📅 各年代电影数量:")
df["year_decade"] = df["year"].astype(str).str[:3] + "0s"
decade_counts = df[df["year"] != "N/A"]["year_decade"].value_counts().sort_index()
for decade, count in decade_counts.items():
print(f" {decade}: {count} 部")
def main():
print("🎬 豆瓣电影Top250爬虫")
print("="*50)
# 爬取数据
movies = collect_all_movies()
# 转换为DataFrame
df = pd.DataFrame(movies)
# 保存数据
df.to_csv("douban_top250.csv", index=False, encoding="utf-8-sig")
print(f"\n✅ 数据已保存到 douban_top250.csv")
# 分析数据
analyze_movies(df)
if __name__ == "__main__":
main()
8.3 项目三:学生成绩管理系统
技术栈:面向对象、文件操作、异常处理
"""
学生成绩管理系统
功能:添加、查询、修改、删除、统计、保存/加载
"""
import json
import os
from datetime import datetime
class Student:
"""学生类"""
def __init__(self, student_id, name, scores=None):
self.student_id = student_id
self.name = name
self.scores = scores if scores else {}
def add_score(self, subject, score):
"""添加/修改成绩"""
if 0 <= score <= 100:
self.scores[subject] = score
return True
return False
def get_average(self):
"""计算平均分"""
if not self.scores:
return 0
return sum(self.scores.values()) / len(self.scores)
def get_total(self):
"""计算总分"""
return sum(self.scores.values())
def to_dict(self):
"""转为字典(用于JSON序列化)"""
return {
"student_id": self.student_id,
"name": self.name,
"scores": self.scores,
"created_at": datetime.now().isoformat()
}
@classmethod
def from_dict(cls, data):
"""从字典创建学生对象"""
student = cls(data["student_id"], data["name"], data["scores"])
return student
def __str__(self):
return f"{self.student_id}\t{self.name}\t总分:{self.get_total()}\t平均:{self.get_average():.1f}"
class StudentManager:
"""学生管理系统"""
def __init__(self, data_file="students.json"):
self.data_file = data_file
self.students = {}
self.load_data()
def add_student(self, student_id, name):
"""添加学生"""
if student_id in self.students:
print(f"学生 {student_id} 已存在")
return False
self.students[student_id] = Student(student_id, name)
print(f"✅ 添加学生成功: {name}")
self.save_data()
return True
def add_score(self, student_id, subject, score):
"""添加成绩"""
if student_id not in self.students:
print(f"学生 {student_id} 不存在")
return False
if self.students[student_id].add_score(subject, score):
print(f"✅ 添加成绩成功: {subject} = {score}")
self.save_data()
return True
else:
print("❌ 成绩必须在0-100之间")
return False
def query_student(self, student_id):
"""查询学生"""
if student_id not in self.students:
print(f"学生 {student_id} 不存在")
return None
student = self.students[student_id]
print(f"\n📋 学生信息:")
print(f" 学号: {student.student_id}")
print(f" 姓名: {student.name}")
print(f" 成绩:")
for subject, score in student.scores.items():
print(f" {subject}: {score}")
print(f" 总分: {student.get_total()}")
print(f" 平均: {student.get_average():.1f}")
return student
def list_all(self):
"""列出所有学生"""
if not self.students:
print("暂无学生数据")
return
print(f"\n{'='*60}")
print(f"学生列表 (共{len(self.students)}人)")
print(f"{'='*60}")
print(f"学号\t姓名\t总分\t平均分")
print(f"{'-'*60}")
for student in self.students.values():
print(student)
print(f"{'='*60}")
def get_statistics(self):
"""统计信息"""
if not self.students:
print("暂无数据")
return
averages = [s.get_average() for s in self.students.values()]
print(f"\n📊 统计信息:")
print(f" 学生总数: {len(self.students)}")
print(f" 平均分最高: {max(averages):.1f}")
print(f" 平均分最低: {min(averages):.1f}")
print(f" 班级平均: {sum(averages)/len(averages):.1f}")
# 分数段统计
excellent = sum(1 for a in averages if a >= 90)
good = sum(1 for a in averages if 80 <= a < 90)
pass_count = sum(1 for a in averages if 60 <= a < 80)
fail = sum(1 for a in averages if a < 60)
print(f"\n 分数段分布:")
print(f" 优秀(≥90): {excellent}人")
print(f" 良好(80-89): {good}人")
print(f" 及格(60-79): {pass_count}人")
print(f" 不及格(<60): {fail}人")
def remove_student(self, student_id):
"""删除学生"""
if student_id in self.students:
name = self.students[student_id].name
del self.students[student_id]
print(f"✅ 删除学生成功: {name}")
self.save_data()
return True
print(f"学生 {student_id} 不存在")
return False
def save_data(self):
"""保存数据到JSON文件"""
data = {
student_id: student.to_dict()
for student_id, student in self.students.items()
}
with open(self.data_file, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def load_data(self):
"""从JSON文件加载数据"""
if not os.path.exists(self.data_file):
return
try:
with open(self.data_file, "r", encoding="utf-8") as f:
data = json.load(f)
for student_id, student_data in data.items():
self.students[student_id] = Student.from_dict(student_data)
print(f"📂 加载了 {len(self.students)} 条学生数据")
except Exception as e:
print(f"加载数据失败: {e}")
def show_menu():
"""显示菜单"""
print("\n" + "="*40)
print(" 学生成绩管理系统")
print("="*40)
print("1. 添加学生")
print("2. 添加成绩")
print("3. 查询学生")
print("4. 显示所有学生")
print("5. 统计信息")
print("6. 删除学生")
print("0. 退出")
print("="*40)
def main():
manager = StudentManager()
while True:
show_menu()
choice = input("请选择操作: ").strip()
if choice == "1":
student_id = input("请输入学号: ").strip()
name = input("请输入姓名: ").strip()
manager.add_student(student_id, name)
elif choice == "2":
student_id = input("请输入学号: ").strip()
subject = input("请输入科目: ").strip()
try:
score = float(input("请输入成绩: ").strip())
manager.add_score(student_id, subject, score)
except ValueError:
print("❌ 成绩必须是数字")
elif choice == "3":
student_id = input("请输入学号: ").strip()
manager.query_student(student_id)
elif choice == "4":
manager.list_all()
elif choice == "5":
manager.get_statistics()
elif choice == "6":
student_id = input("请输入学号: ").strip()
manager.remove_student(student_id)
elif choice == "0":
print("👋 感谢使用,再见!")
break
else:
print("❌ 无效选择,请重新输入")
if __name__ == "__main__":
main()
📝 附录:快速参考
常用内置函数速查
函数 说明 示例
print() 输出 print(“Hello”)
input() 输入 name = input()
len() 获取长度 len([1,2,3]) → 3
type() 获取类型 type(123) → <class ‘int’>
int(), str(), float() 类型转换 int(“123”)
range() 生成数字序列 list(range(5)) → [0,1,2,3,4]
enumerate() 带索引遍历 for i, v in enumerate(list)
zip() 并行遍历 zip(list1, list2)
sorted() 排序 sorted([3,1,2]) → [1,2,3]
sum(), min(), max() 统计 sum([1,2,3]) → 6
abs() 绝对值 abs(-5) → 5
round() 四舍五入 round(3.14159, 2) → 3.14
open() 打开文件 open(“file.txt”, “r”)
Python 关键字
False await else import pass
None break except in raise
True class finally is return
and continue for lambda try
as def from nonlocal while
assert del global not with
async elif if or yield
希望这份详尽的Python语法大全与实战指南能帮助你系统掌握Python编程!从基础语法开始,逐步深入到面向对象、异常处理、文件操作,再到实战项目,建议按照章节顺序学习并动手实践每个代码示例。
更多推荐



所有评论(0)