Python基础
Python是一门易学易用的高级编程语言,以简洁的语法和丰富的生态系统而著称。本文将介绍Python的基础知识,帮助您快速入门。
核心概念
类别 | 内容 |
---|---|
语法与数据类型 | 数字、字符串、列表、元组、字典、集合 |
控制流 | 条件语句、循环语句、异常处理 |
函数与模块 | 函数定义、参数传递、返回值、模块导入 |
面向对象 | 类定义、继承、多态、封装 |
标准库 | 常用内置模块和函数 |
1. 基础语法
Python简介
Python由Guido van Rossum于1989年创建,具有以下特点:
- 易于学习:语法简洁清晰
- 易于阅读:代码可读性高
- 可移植性:跨平台运行
- 丰富的库:强大的标准库和第三方生态
环境配置
# 检查Python版本
python --version
# 创建虚拟环境
python -m venv myenv
# 激活虚拟环境
# Windows
myenv\Scripts\activate
# macOS/Linux
source myenv/bin/activate
2. 数据类型
Python是动态类型语言,主要数据类型包括:
基本类型
# 数字
integer = 42 # 整数
float_num = 3.14 # 浮点数
complex_num = 1+2j # 复数
# 字符串
text = "Hello, World!"
multiline = '''多行
字符串'''
# 布尔值
is_true = True
is_false = False
容器类型
# 列表 - 有序、可变
fruits = ["苹果", "香蕉", "橙子"]
mixed = [1, "苹果", True, 3.14]
# 元组 - 有序、不可变
coordinates = (10.0, 20.0)
# 字典 - 键值对
person = {
"name": "张三",
"age": 30,
"city": "北京"
}
# 集合 - 无序、无重复
unique_numbers = {1, 2, 3, 4, 5}
3. 控制流
条件语句
age = 18
if age >= 18:
print("成年人")
elif age >= 13:
print("青少年")
else:
print("儿童")
# 条件表达式(三元运算符)
status = "成年" if age >= 18 else "未成年"
循环语句
# for循环
for i in range(5): # 0, 1, 2, 3, 4
print(i)
# 遍历列表
for fruit in fruits:
print(fruit)
# while循环
count = 0
while count < 5:
print(count)
count += 1
4. 函数与模块
函数定义
# 定义函数
def greet(name):
"""这是函数的文档字符串,描述函数的功能"""
return f"Hello, {name}!"
# 调用函数
message = greet("Python")
print(message) # 输出: Hello, Python!
参数传递
def add(a, b):
return a + b
result = add(3, 5) # 8
返回值
# 返回单个值
def square(x):
return x ** 2
# 返回多个值(实际上是返回一个元组)
def min_max(numbers):
return min(numbers), max(numbers)
minimum, maximum = min_max([1, 2, 3, 4, 5])
print(minimum, maximum) # 1 5
# 不返回值(默认返回None)
def say_hello(name):
print(f"Hello, {name}!")
result = say_hello("Python") # 返回值是None
5. 面向对象
类定义
# 定义一个简单的类
class Person:
"""表示一个人的类"""
# 类变量(被所有实例共享)
species = "Homo sapiens"
# 初始化方法(构造函数)
def __init__(self, name, age):
# 实例变量(每个实例独有)
self.name = name
self.age = age
# 实例方法
def say_hello(self):
return f"你好,我是{self.name},{self.age}岁"
def have_birthday(self):
self.age += 1
# 创建类的实例(对象)
person1 = Person("张三", 30)
person2 = Person("李四", 25)
# 访问实例变量
print(person1.name) # 张三
print(person2.age) # 25
# 调用实例方法
print(person1.say_hello()) # 你好,我是张三,30岁
person1.have_birthday()
print(person1.age) # 31
# 访问类变量
print(Person.species) # Homo sapiens
print(person1.species) # Homo sapiens
继承
# 基类(父类)
class Animal:
def __init__(self, name, species):
self.name = name
self.species = species
def make_sound(self):
print("一般动物的声音")
def __str__(self):
return f"{self.name}是一只{self.species}"
# 派生类(子类)
class Dog(Animal):
def __init__(self, name, breed):
# 调用父类的初始化方法
super().__init__(name, species="狗")
self.breed = breed
# 重写父类方法
def make_sound(self):
print("汪汪!")
# 添加子类特有的方法
def fetch(self):
print(f"{self.name}在捡球")
# 创建实例
dog = Dog("旺财", "金毛")
print(dog) # 旺财是一只狗
dog.make_sound() # 汪汪!
dog.fetch() # 旺财在捡球
多态
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "汪汪!"
class Cat(Animal):
def speak(self):
return "喵喵!"
class Duck(Animal):
def speak(self):
return "嘎嘎!"
# 多态函数
def animal_sound(animal):
return animal.speak()
# 使用不同类型的对象
dog = Dog()
cat = Cat()
duck = Duck()
print(animal_sound(dog)) # 汪汪!
print(animal_sound(cat)) # 喵喵!
print(animal_sound(duck)) # 嘎嘎!
6. 标准库
Python的强大之处在于其丰富的标准库,这些库随Python一起安装,无需额外下载。以下是一些常用的标准库:
操作系统接口
os模块
提供与操作系统交互的功能:
import os
# 当前工作目录
print(os.getcwd()) # 例如 '/home/user/projects'
# 改变当前工作目录
os.chdir('/tmp')
# 列出目录内容
print(os.listdir()) # 例如 ['file1.txt', 'file2.py', 'dir1']
# 创建目录
os.mkdir('new_directory')
os.makedirs('nested/directory/path', exist_ok=True) # 递归创建
# 删除文件和目录
os.remove('file.txt')
os.rmdir('empty_directory') # 只能删除空目录
import shutil
shutil.rmtree('directory_with_files') # 递归删除目录
# 重命名
os.rename('old_name.txt', 'new_name.txt')
# 获取文件信息
print(os.path.getsize('file.txt')) # 文件大小(字节)
print(os.path.getmtime('file.txt')) # 最后修改时间(时间戳)
# 检查路径
print(os.path.exists('file.txt')) # 是否存在
print(os.path.isfile('file.txt')) # 是否为文件
print(os.path.isdir('directory')) # 是否为目录
# 路径操作
print(os.path.join('dir', 'subdir', 'file.txt')) # 连接路径
print(os.path.split('/path/to/file.txt')) # 分割路径和文件名
print(os.path.basename('/path/to/file.txt')) # 获取文件名
print(os.path.dirname('/path/to/file.txt')) # 获取目录路径
print(os.path.splitext('file.txt')) # 分割文件名和扩展名
# 环境变量
print(os.environ.get('HOME')) # 获取环境变量
os.environ['TEMP_VAR'] = 'value' # 设置环境变量(仅当前进程有效)
sys模块
提供对Python解释器的访问:
import sys
# 命令行参数
print(sys.argv) # 脚本名称和命令行参数列表
# Python版本
print(sys.version) # 详细版本信息
print(sys.version_info) # 版本信息元组
# 平台信息
print(sys.platform) # 运行平台标识(例如 'linux', 'win32', 'darwin')
# 模块搜索路径
print(sys.path) # 模块搜索路径列表
sys.path.append('/path/to/my/modules') # 添加自定义模块路径
# 标准输入输出
sys.stdout.write("Hello\n") # 写入标准输出
sys.stderr.write("Error\n") # 写入标准错误
# 退出程序
# sys.exit(0) # 正常退出
# sys.exit(1) # 带错误代码退出
文件和目录管理
shutil模块
提供高级文件操作:
import shutil
# 复制文件
shutil.copy('source.txt', 'dest.txt') # 复制文件
shutil.copy2('source.txt', 'dest.txt') # 复制文件和元数据
# 复制目录
shutil.copytree('source_dir', 'dest_dir') # 递归复制整个目录
# 移动文件或目录
shutil.move('source.txt', 'dest.txt')
# 删除目录
shutil.rmtree('directory_path') # 递归删除目录及其内容
# 归档操作
shutil.make_archive('archive_name', 'zip', 'directory_to_archive') # 创建ZIP归档
glob模块
使用通配符查找文件:
import glob
# 查找匹配的文件
python_files = glob.glob('*.py') # 当前目录中所有.py文件
print(python_files)
# 递归查找
all_python_files = glob.glob('**/*.py', recursive=True) # 所有子目录中的.py文件
print(all_python_files)
# 多模式匹配
image_files = glob.glob('*.{jpg,png,gif}', recursive=True) # 所有图像文件
print(image_files)
日期和时间
datetime模块
处理日期和时间:
from datetime import datetime, date, time, timedelta
# 当前日期和时间
now = datetime.now()
print(now) # 例如 2023-11-07 15:30:25.123456
# 创建特定日期和时间
dt = datetime(2023, 11, 7, 15, 30)
print(dt) # 2023-11-07 15:30:00
# 日期和时间分量
print(dt.year, dt.month, dt.day) # 2023 11 7
print(dt.hour, dt.minute, dt.second) # 15 30 0
# 只有日期或时间
today = date.today()
print(today) # 例如 2023-11-07
current_time = datetime.now().time()
print(current_time) # 例如 15:30:25.123456
# 日期时间算术
tomorrow = today + timedelta(days=1)
print(tomorrow)
next_week = today + timedelta(weeks=1)
print(next_week)
# 格式化日期时间
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(formatted) # 例如 2023-11-07 15:30:25
# 解析日期时间字符串
parsed = datetime.strptime("2023-11-07 15:30:25", "%Y-%m-%d %H:%M:%S")
print(parsed) # 2023-11-07 15:30:25
time模块
处理时间相关操作:
import time
# 当前时间戳(秒)
timestamp = time.time()
print(timestamp) # 例如 1699368625.123456
# 将时间戳转换为本地时间
local_time = time.localtime(timestamp)
print(time.strftime("%Y-%m-%d %H:%M:%S", local_time))
# 暂停执行
time.sleep(1) # 暂停1秒
# 测量执行时间
start = time.time()
time.sleep(0.5)
end = time.time()
print(f"执行时间: {end - start} 秒") # 约0.5秒
数据处理
json模块
处理JSON数据:
import json
# Python字典
data = {
"name": "张三",
"age": 30,
"city": "北京",
"languages": ["Python", "JavaScript"],
"active": True,
"height": 175.5
}
# 转换为JSON字符串
json_string = json.dumps(data, ensure_ascii=False, indent=4)
print(json_string)
# 将JSON字符串转换回Python对象
parsed_data = json.loads(json_string)
print(parsed_data["name"]) # 张三
# 写入JSON文件
with open('data.json', 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
# 读取JSON文件
with open('data.json', 'r', encoding='utf-8') as file:
loaded_data = json.load(file)
print(loaded_data)
csv模块
处理CSV文件:
import csv
# 写入CSV文件
with open('data.csv', 'w', newline='', encoding='utf-8') as file:
writer = csv.writer(file)
# 写入标题行
writer.writerow(['Name', 'Age', 'City'])
# 写入数据行
writer.writerow(['张三', 30, '北京'])
writer.writerow(['李四', 25, '上海'])
writer.writerow(['王五', 35, '广州'])
# 读取CSV文件
with open('data.csv', 'r', encoding='utf-8') as file:
reader = csv.reader(file)
for row in reader:
print(row) # 例如 ['张三', '30', '北京']
# 使用DictReader和DictWriter
with open('data_dict.csv', 'w', newline='', encoding='utf-8') as file:
fieldnames = ['name', 'age', 'city']
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader() # 写入标题行
writer.writerow({'name': '张三', 'age': 30, 'city': '北京'})
writer.writerow({'name': '李四', 'age': 25, 'city': '上海'})
with open('data_dict.csv', 'r', encoding='utf-8') as file:
reader = csv.DictReader(file)
for row in reader:
print(row['name'], row['age']) # 例如 张三 30
数学和随机数
math模块
提供数学函数:
import math
# 常量
print(math.pi) # 3.141592653589793
print(math.e) # 2.718281828459045
# 基本函数
print(math.sqrt(16)) # 平方根: 4.0
print(math.pow(2, 3)) # 幂运算: 8.0
print(math.log(100, 10)) # 以10为底的对数: 2.0
print(math.log10(100)) # 以10为底的对数: 2.0
print(math.log(math.e)) # 自然对数: 1.0
# 三角函数(参数为弧度)
print(math.sin(math.pi/2)) # 正弦: 1.0
print(math.cos(0)) # 余弦: 1.0
print(math.tan(math.pi/4)) # 正切: 1.0
# 角度与弧度转换
print(math.degrees(math.pi)) # 弧度转角度: 180.0
print(math.radians(180)) # 角度转弧度: 3.141592653589793
# 向上和向下取整
print(math.ceil(4.1)) # 向上取整: 5
print(math.floor(4.9)) # 向下取整: 4
random模块
生成随机数:
import random
# 随机浮点数
print(random.random()) # 0.0到1.0之间的随机浮点数
print(random.uniform(1, 10)) # 1.0到10.0之间的随机浮点数
# 随机整数
print(random.randint(1, 10)) # 1到10之间的随机整数(包括1和10)
print(random.randrange(1, 10)) # 1到9之间的随机整数(包括1,不包括10)
print(random.randrange(0, 101, 5)) # 0到100之间的5的倍数
# 随机选择
print(random.choice(['苹果', '香蕉', '橙子'])) # 随机选择一个元素
print(random.sample(['苹果', '香蕉', '橙子', '葡萄'], 2)) # 随机选择2个元素
# 随机打乱
items = [1, 2, 3, 4, 5]
random.shuffle(items)
print(items) # 随机顺序的列表
正则表达式
re模块
用于字符串模式匹配:
import re
text = "联系方式:电话13812345678,邮箱user@example.com"
# 查找匹配
phone = re.search(r'1\d{10}', text)
if phone:
print("找到手机号:", phone.group()) # 13812345678
# 查找所有匹配
emails = re.findall(r'[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+', text)
print(emails) # ['user@example.com']
# 替换
new_text = re.sub(r'1\d{10}', '1XXXXXXXXXX', text)
print(new_text) # 联系方式:电话1XXXXXXXXXX,邮箱user@example.com
# 分割字符串
words = re.split(r'[,,:]', text)
print(words) # ['联系方式', '电话13812345678', '邮箱user@example.com']
# 编译正则表达式(提高性能)
pattern = re.compile(r'\d+')
numbers = pattern.findall(text)
print(numbers) # ['13812345678']
# 组和命名组
date_text = "日期:2023-11-07,时间:15:30:25"
pattern = re.compile(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})')
match = pattern.search(date_text)
if match:
print("年:", match.group('year')) # 2023
print("月:", match.group('month')) # 11
print("日:", match.group('day')) # 07
网络通信
urllib模块
用于URL处理:
from urllib import request, parse
# 发送GET请求
response = request.urlopen('https://api.example.com/data')
content = response.read()
print(content) # 二进制响应内容
# 读取响应内容
text_content = content.decode('utf-8') # 转换为文本
print(text_content)
# URL编码参数
params = {'q': '查询', 'lang': 'zh'}
encoded_params = parse.urlencode(params)
url = f'https://example.com/search?{encoded_params}'
print(url) # https://example.com/search?q=%E6%9F%A5%E8%AF%A2&lang=zh
# 解析URL
parsed_url = parse.urlparse('https://www.example.com:8080/path?query=value#fragment')
print(parsed_url.scheme) # https
print(parsed_url.netloc) # www.example.com:8080
print(parsed_url.path) # /path
print(parsed_url.query) # query=value
print(parsed_url.fragment) # fragment
socket模块
低级网络接口:
import socket
# 创建TCP客户端
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client.connect(('www.example.com', 80))
# 发送HTTP请求
request = b"GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"
client.sendall(request)
# 接收响应
response = b''
chunk = client.recv(4096)
while chunk:
response += chunk
chunk = client.recv(4096)
print(response.decode('utf-8'))
finally:
client.close()
数据持久化
pickle模块
序列化Python对象:
import pickle
# 定义一个对象
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"你好,我是{self.name},{self.age}岁"
# 创建实例
person = Person("张三", 30)
# 序列化对象到文件
with open('person.pkl', 'wb') as file:
pickle.dump(person, file)
# 从文件反序列化对象
with open('person.pkl', 'rb') as file:
loaded_person = pickle.load(file)
# 使用反序列化对象
print(loaded_person.name) # 张三
print(loaded_person.greet()) # 你好,我是张三,30岁
# 序列化多个对象
data = [person, {"key": "value"}, [1, 2, 3]]
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
# 使用pickle字符串
serialized = pickle.dumps(person)
print(serialized) # 二进制数据
deserialized = pickle.loads(serialized)
print(deserialized.name) # 张三
shelve模块
持久化字典:
import shelve
# 创建/打开shelve数据库
with shelve.open('mydata') as db:
# 存储数据(像字典一样使用)
db['name'] = "张三"
db['age'] = 30
db['skills'] = ["Python", "JavaScript", "SQL"]
# 一个复杂的对象
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
db['person'] = Person("李四", 25)
# 读取数据
with shelve.open('mydata') as db:
print(db['name']) # 张三
print(db['skills']) # ["Python", "JavaScript", "SQL"]
person = db['person']
print(person.name) # 李四
# 遍历所有键
for key in db.keys():
print(key)
# 检查键是否存在
if 'age' in db:
print(f"年龄: {db['age']}")
并发编程
threading模块
多线程编程:
import threading
import time
# 定义线程函数
def worker(name, delay):
print(f"{name} 开始工作")
time.sleep(delay)
print(f"{name} 工作结束")
# 创建线程
t1 = threading.Thread(target=worker, args=("线程1", 2))
t2 = threading.Thread(target=worker, args=("线程2", 1))
# 启动线程
t1.start()
t2.start()
# 等待线程完成
t1.join()
t2.join()
print("所有线程已完成")
# 使用线程锁
counter = 0
counter_lock = threading.Lock()
def increment_counter(count):
global counter
for _ in range(count):
with counter_lock: # 获取锁
counter += 1
threads = []
for i in range(5):
t = threading.Thread(target=increment_counter, args=(100000,))
threads.append(t)
t.start()
for t in threads:
t.join()
print(f"计数器最终值: {counter}") # 500000
multiprocessing模块
多进程编程:
import multiprocessing
import time
def worker(name):
print(f"{name} 开始工作 (PID: {multiprocessing.current_process().pid})")
time.sleep(2)
print(f"{name} 工作结束")
if __name__ == '__main__':
# 创建进程
p1 = multiprocessing.Process(target=worker, args=("进程1",))
p2 = multiprocessing.Process(target=worker, args=("进程2",))
# 启动进程
p1.start()
p2.start()
# 等待进程完成
p1.join()
p2.join()
print("所有进程已完成")
# 使用进程池
with multiprocessing.Pool(processes=3) as pool:
results = pool.map(worker, ["进程A", "进程B", "进程C"])
其他实用标准库
- argparse: 命令行参数解析
- logging: 日志记录
- unittest: 单元测试
- collections: 提供额外的容器数据类型
- itertools: 迭代器函数
- functools: 高阶函数和可调用对象上的操作
- hashlib: 安全哈希和消息摘要
- base64: Base16、Base32、Base64编码
- zlib: 数据压缩
- email: 电子邮件和MIME处理
- xml: XML处理
- html: HTML处理
- http: HTTP协议客户端
- urllib: URL处理
- sqlite3: SQLite数据库访问
- asyncio: 异步I/O
7. 函数与模块
函数定义
# 定义函数
def greet(name):
"""这是函数的文档字符串,描述函数的功能"""
return f"Hello, {name}!"
# 调用函数
message = greet("Python")
print(message) # 输出: Hello, Python!
参数传递
def add(a, b):
return a + b
result = add(3, 5) # 8
返回值
# 返回单个值
def square(x):
return x ** 2
# 返回多个值(实际上是返回一个元组)
def min_max(numbers):
return min(numbers), max(numbers)
minimum, maximum = min_max([1, 2, 3, 4, 5])
print(minimum, maximum) # 1 5
# 不返回值(默认返回None)
def say_hello(name):
print(f"Hello, {name}!")
result = say_hello("Python") # 返回值是None
8. 面向对象
类定义
# 定义一个简单的类
class Person:
"""表示一个人的类"""
# 类变量(被所有实例共享)
species = "Homo sapiens"
# 初始化方法(构造函数)
def __init__(self, name, age):
# 实例变量(每个实例独有)
self.name = name
self.age = age
# 实例方法
def say_hello(self):
return f"你好,我是{self.name},{self.age}岁"
def have_birthday(self):
self.age += 1
# 创建类的实例(对象)
person1 = Person("张三", 30)
person2 = Person("李四", 25)
# 访问实例变量
print(person1.name) # 张三
print(person2.age) # 25
# 调用实例方法
print(person1.say_hello()) # 你好,我是张三,30岁
person1.have_birthday()
print(person1.age) # 31
# 访问类变量
print(Person.species) # Homo sapiens
print(person1.species) # Homo sapiens
继承
# 基类(父类)
class Animal:
def __init__(self, name, species):
self.name = name
self.species = species
def make_sound(self):
print("一般动物的声音")
def __str__(self):
return f"{self.name}是一只{self.species}"
# 派生类(子类)
class Dog(Animal):
def __init__(self, name, breed):
# 调用父类的初始化方法
super().__init__(name, species="狗")
self.breed = breed
# 重写父类方法
def make_sound(self):
print("汪汪!")
# 添加子类特有的方法
def fetch(self):
print(f"{self.name}在捡球")
# 创建实例
dog = Dog("旺财", "金毛")
print(dog) # 旺财是一只狗
dog.make_sound() # 汪汪!
dog.fetch() # 旺财在捡球
多态
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "汪汪!"
class Cat(Animal):
def speak(self):
return "喵喵!"
class Duck(Animal):
def speak(self):
return "嘎嘎!"
# 多态函数
def animal_sound(animal):
return animal.speak()
# 使用不同类型的对象
dog = Dog()
cat = Cat()
duck = Duck()
print(animal_sound(dog)) # 汪汪!
print(animal_sound(cat)) # 喵喵!
print(animal_sound(duck)) # 嘎嘎!
9. 标准库
Python的强大之处在于其丰富的标准库,这些库随Python一起安装,无需额外下载。以下是一些常用的标准库:
操作系统接口
os模块
提供与操作系统交互的功能:
import os
# 当前工作目录
print(os.getcwd()) # 例如 '/home/user/projects'
# 改变当前工作目录
os.chdir('/tmp')
# 列出目录内容
print(os.listdir()) # 例如 ['file1.txt', 'file2.py', 'dir1']
# 创建目录
os.mkdir('new_directory')
os.makedirs('nested/directory/path', exist_ok=True) # 递归创建
# 删除文件和目录
os.remove('file.txt')
os.rmdir('empty_directory') # 只能删除空目录
import shutil
shutil.rmtree('directory_with_files') # 递归删除目录
# 重命名
os.rename('old_name.txt', 'new_name.txt')
# 获取文件信息
print(os.path.getsize('file.txt')) # 文件大小(字节)
print(os.path.getmtime('file.txt')) # 最后修改时间(时间戳)
# 检查路径
print(os.path.exists('file.txt')) # 是否存在
print(os.path.isfile('file.txt')) # 是否为文件
print(os.path.isdir('directory')) # 是否为目录
# 路径操作
print(os.path.join('dir', 'subdir', 'file.txt')) # 连接路径
print(os.path.split('/path/to/file.txt')) # 分割路径和文件名
print(os.path.basename('/path/to/file.txt')) # 获取文件名
print(os.path.dirname('/path/to/file.txt')) # 获取目录路径
print(os.path.splitext('file.txt')) # 分割文件名和扩展名
# 环境变量
print(os.environ.get('HOME')) # 获取环境变量
os.environ['TEMP_VAR'] = 'value' # 设置环境变量(仅当前进程有效)
sys模块
提供对Python解释器的访问:
import sys
# 命令行参数
print(sys.argv) # 脚本名称和命令行参数列表
# Python版本
print(sys.version) # 详细版本信息
print(sys.version_info) # 版本信息元组
# 平台信息
print(sys.platform) # 运行平台标识(例如 'linux', 'win32', 'darwin')
# 模块搜索路径
print(sys.path) # 模块搜索路径列表
sys.path.append('/path/to/my/modules') # 添加自定义模块路径
# 标准输入输出
sys.stdout.write("Hello\n") # 写入标准输出
sys.stderr.write("Error\n") # 写入标准错误
# 退出程序
# sys.exit(0) # 正常退出
# sys.exit(1) # 带错误代码退出
文件和目录管理
shutil模块
提供高级文件操作:
import shutil
# 复制文件
shutil.copy('source.txt', 'dest.txt') # 复制文件
shutil.copy2('source.txt', 'dest.txt') # 复制文件和元数据
# 复制目录
shutil.copytree('source_dir', 'dest_dir') # 递归复制整个目录
# 移动文件或目录
shutil.move('source.txt', 'dest.txt')
# 删除目录
shutil.rmtree('directory_path') # 递归删除目录及其内容
# 归档操作
shutil.make_archive('archive_name', 'zip', 'directory_to_archive') # 创建ZIP归档
glob模块
使用通配符查找文件:
import glob
# 查找匹配的文件
python_files = glob.glob('*.py') # 当前目录中所有.py文件
print(python_files)
# 递归查找
all_python_files = glob.glob('**/*.py', recursive=True) # 所有子目录中的.py文件
print(all_python_files)
# 多模式匹配
image_files = glob.glob('*.{jpg,png,gif}', recursive=True) # 所有图像文件
print(image_files)
日期和时间
datetime模块
处理日期和时间:
from datetime import datetime, date, time, timedelta
# 当前日期和时间
now = datetime.now()
print(now) # 例如 2023-11-07 15:30:25.123456
# 创建特定日期和时间
dt = datetime(2023, 11, 7, 15, 30)
print(dt) # 2023-11-07 15:30:00
# 日期和时间分量
print(dt.year, dt.month, dt.day) # 2023 11 7
print(dt.hour, dt.minute, dt.second) # 15 30 0
# 只有日期或时间
today = date.today()
print(today) # 例如 2023-11-07
current_time = datetime.now().time()
print(current_time) # 例如 15:30:25.123456
# 日期时间算术
tomorrow = today + timedelta(days=1)
print(tomorrow)
next_week = today + timedelta(weeks=1)
print(next_week)
# 格式化日期时间
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(formatted) # 例如 2023-11-07 15:30:25
# 解析日期时间字符串
parsed = datetime.strptime("2023-11-07 15:30:25", "%Y-%m-%d %H:%M:%S")
print(parsed) # 2023-11-07 15:30:25
time模块
处理时间相关操作:
import time
# 当前时间戳(秒)
timestamp = time.time()
print(timestamp) # 例如 1699368625.123456
# 将时间戳转换为本地时间
local_time = time.localtime(timestamp)
print(time.strftime("%Y-%m-%d %H:%M:%S", local_time))
# 暂停执行
time.sleep(1) # 暂停1秒
# 测量执行时间
start = time.time()
time.sleep(0.5)
end = time.time()
print(f"执行时间: {end - start} 秒") # 约0.5秒
数据处理
json模块
处理JSON数据:
import json
# Python字典
data = {
"name": "张三",
"age": 30,
"city": "北京",
"languages": ["Python", "JavaScript"],
"active": True,
"height": 175.5
}
# 转换为JSON字符串
json_string = json.dumps(data, ensure_ascii=False, indent=4)
print(json_string)
# 将JSON字符串转换回Python对象
parsed_data = json.loads(json_string)
print(parsed_data["name"]) # 张三
# 写入JSON文件
with open('data.json', 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
# 读取JSON文件
with open('data.json', 'r', encoding='utf-8') as file:
loaded_data = json.load(file)
print(loaded_data)
csv模块
处理CSV文件:
import csv
# 写入CSV文件
with open('data.csv', 'w', newline='', encoding='utf-8') as file:
writer = csv.writer(file)
# 写入标题行
writer.writerow(['Name', 'Age', 'City'])
# 写入数据行
writer.writerow(['张三', 30, '北京'])
writer.writerow(['李四', 25, '上海'])
writer.writerow(['王五', 35, '广州'])
# 读取CSV文件
with open('data.csv', 'r', encoding='utf-8') as file:
reader = csv.reader(file)
for row in reader:
print(row) # 例如 ['张三', '30', '北京']
# 使用DictReader和DictWriter
with open('data_dict.csv', 'w', newline='', encoding='utf-8') as file:
fieldnames = ['name', 'age', 'city']
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader() # 写入标题行
writer.writerow({'name': '张三', 'age': 30, 'city': '北京'})
writer.writerow({'name': '李四', 'age': 25, 'city': '上海'})
with open('data_dict.csv', 'r', encoding='utf-8') as file:
reader = csv.DictReader(file)
for row in reader:
print(row['name'], row['age']) # 例如 张三 30
数学和随机数
math模块
提供数学函数:
import math
# 常量
print(math.pi) # 3.141592653589793
print(math.e) # 2.718281828459045
# 基本函数
print(math.sqrt(16)) # 平方根: 4.0
print(math.pow(2, 3)) # 幂运算: 8.0
print(math.log(100, 10)) # 以10为底的对数: 2.0
print(math.log10(100)) # 以10为底的对数: 2.0
print(math.log(math.e)) # 自然对数: 1.0
# 三角函数(参数为弧度)
print(math.sin(math.pi/2)) # 正弦: 1.0
print(math.cos(0)) # 余弦: 1.0
print(math.tan(math.pi/4)) # 正切: 1.0
# 角度与弧度转换
print(math.degrees(math.pi)) # 弧度转角度: 180.0
print(math.radians(180)) # 角度转弧度: 3.141592653589793
# 向上和向下取整
print(math.ceil(4.1)) # 向上取整: 5
print(math.floor(4.9)) # 向下取整: 4
random模块
生成随机数:
import random
# 随机浮点数
print(random.random()) # 0.0到1.0之间的随机浮点数
print(random.uniform(1, 10)) # 1.0到10.0之间的随机浮点数
# 随机整数
print(random.randint(1, 10)) # 1到10之间的随机整数(包括1和10)
print(random.randrange(1, 10)) # 1到9之间的随机整数(包括1,不包括10)
print(random.randrange(0, 101, 5)) # 0到100之间的5的倍数
# 随机选择
print(random.choice(['苹果', '香蕉', '橙子'])) # 随机选择一个元素
print(random.sample(['苹果', '香蕉', '橙子', '葡萄'], 2)) # 随机选择2个元素
# 随机打乱
items = [1, 2, 3, 4, 5]
random.shuffle(items)
print(items) # 随机顺序的列表
正则表达式
re模块
用于字符串模式匹配:
import re
text = "联系方式:电话13812345678,邮箱user@example.com"
# 查找匹配
phone = re.search(r'1\d{10}', text)
if phone:
print("找到手机号:", phone.group()) # 13812345678
# 查找所有匹配
emails = re.findall(r'[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+', text)
print(emails) # ['user@example.com']
# 替换
new_text = re.sub(r'1\d{10}', '1XXXXXXXXXX', text)
print(new_text) # 联系方式:电话1XXXXXXXXXX,邮箱user@example.com
# 分割字符串
words = re.split(r'[,,:]', text)
print(words) # ['联系方式', '电话13812345678', '邮箱user@example.com']
# 编译正则表达式(提高性能)
pattern = re.compile(r'\d+')
numbers = pattern.findall(text)
print(numbers) # ['13812345678']
# 组和命名组
date_text = "日期:2023-11-07,时间:15:30:25"
pattern = re.compile(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})')
match = pattern.search(date_text)
if match:
print("年:", match.group('year')) # 2023
print("月:", match.group('month')) # 11
print("日:", match.group('day')) # 07
网络通信
urllib模块
用于URL处理:
from urllib import request, parse
# 发送GET请求
response = request.urlopen('https://api.example.com/data')
content = response.read()
print(content) # 二进制响应内容
# 读取响应内容
text_content = content.decode('utf-8') # 转换为文本
print(text_content)
# URL编码参数
params = {'q': '查询', 'lang': 'zh'}
encoded_params = parse.urlencode(params)
url = f'https://example.com/search?{encoded_params}'
print(url) # https://example.com/search?q=%E6%9F%A5%E8%AF%A2&lang=zh
# 解析URL
parsed_url = parse.urlparse('https://www.example.com:8080/path?query=value#fragment')
print(parsed_url.scheme) # https
print(parsed_url.netloc) # www.example.com:8080
print(parsed_url.path) # /path
print(parsed_url.query) # query=value
print(parsed_url.fragment) # fragment
socket模块
低级网络接口:
import socket
# 创建TCP客户端
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client.connect(('www.example.com', 80))
# 发送HTTP请求
request = b"GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"
client.sendall(request)
# 接收响应
response = b''
chunk = client.recv(4096)
while chunk:
response += chunk
chunk = client.recv(4096)
print(response.decode('utf-8'))
finally:
client.close()
数据持久化
pickle模块
序列化Python对象:
import pickle
# 定义一个对象
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"你好,我是{self.name},{self.age}岁"
# 创建实例
person = Person("张三", 30)
# 序列化对象到文件
with open('person.pkl', 'wb') as file:
pickle.dump(person, file)
# 从文件反序列化对象
with open('person.pkl', 'rb') as file:
loaded_person = pickle.load(file)
# 使用反序列化对象
print(loaded_person.name) # 张三
print(loaded_person.greet()) # 你好,我是张三,30岁
# 序列化多个对象
data = [person, {"key": "value"}, [1, 2, 3]]
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
# 使用pickle字符串
serialized = pickle.dumps(person)
print(serialized) # 二进制数据
deserialized = pickle.loads(serialized)
print(deserialized.name) # 张三
shelve模块
持久化字典:
import shelve
# 创建/打开shelve数据库
with shelve.open('mydata') as db:
# 存储数据(像字典一样使用)
db['name'] = "张三"
db['age'] = 30
db['skills'] = ["Python", "JavaScript", "SQL"]
# 一个复杂的对象
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
db['person'] = Person("李四", 25)
# 读取数据
with shelve.open('mydata') as db:
print(db['name']) # 张三
print(db['skills']) # ["Python", "JavaScript", "SQL"]
person = db['person']
print(person.name) # 李四
# 遍历所有键
for key in db.keys():
print(key)
# 检查键是否存在
if 'age' in db:
print(f"年龄: {db['age']}")
并发编程
threading模块
多线程编程:
import threading
import time
# 定义线程函数
def worker(name, delay):
print(f"{name} 开始工作")
time.sleep(delay)
print(f"{name} 工作结束")
# 创建线程
t1 = threading.Thread(target=worker, args=("线程1", 2))
t2 = threading.Thread(target=worker, args=("线程2", 1))
# 启动线程
t1.start()
t2.start()
# 等待线程完成
t1.join()
t2.join()
print("所有线程已完成")
# 使用线程锁
counter = 0
counter_lock = threading.Lock()
def increment_counter(count):
global counter
for _ in range(count):
with counter_lock: # 获取锁
counter += 1
threads = []
for i in range(5):
t = threading.Thread(target=increment_counter, args=(100000,))
threads.append(t)
t.start()
for t in threads:
t.join()
print(f"计数器最终值: {counter}") # 500000
multiprocessing模块
多进程编程:
import multiprocessing
import time
def worker(name):
print(f"{name} 开始工作 (PID: {multiprocessing.current_process().pid})")
time.sleep(2)
print(f"{name} 工作结束")
if __name__ == '__main__':
# 创建进程
p1 = multiprocessing.Process(target=worker, args=("进程1",))
p2 = multiprocessing.Process(target=worker, args=("进程2",))
# 启动进程
p1.start()
p2.start()
# 等待进程完成
p1.join()
p2.join()
print("所有进程已完成")
# 使用进程池
with multiprocessing.Pool(processes=3) as pool:
results = pool.map(worker, ["进程A", "进程B", "进程C"])
其他实用标准库
- argparse: 命令行参数解析
- logging: 日志记录
- unittest: 单元测试
- collections: 提供额外的容器数据类型
- itertools: 迭代器函数
- functools: 高阶函数和可调用对象上的操作
- hashlib: 安全哈希和消息摘要
- base64: Base16、Base32、Base64编码
- zlib: 数据压缩
- email: 电子邮件和MIME处理
- xml: XML处理
- html: HTML处理
- http: HTTP协议客户端
- urllib: URL处理
- sqlite3: SQLite数据库访问
- asyncio: 异步I/O
10. 装饰器与单例模式
装饰器基础
装饰器是Python中强大而灵活的编程工具,可以修改或增强函数和类的行为,而不需要直接修改其源代码。
装饰器的定义和使用
装饰器本质上是一个接受函数并返回函数的高阶函数:
# 基本装饰器
def simple_decorator(func):
def wrapper():
print("函数执行前")
func()
print("函数执行后")
return wrapper
# 使用装饰器
@simple_decorator
def hello():
print("Hello, World!")
# 调用装饰后的函数
hello()
# 输出:
# 函数执行前
# Hello, World!
# 函数执行后
# 这等同于
def hello():
print("Hello, World!")
hello = simple_decorator(hello)
装饰带参数函数
def decorator_with_args(func):
def wrapper(*args, **kwargs):
print(f"函数参数: {args}, {kwargs}")
result = func(*args, **kwargs)
print(f"函数返回值: {result}")
return result
return wrapper
@decorator_with_args
def add(a, b):
return a + b
result = add(3, 5)
# 输出:
# 函数参数: (3, 5), {}
# 函数返回值: 8
print(f"结果: {result}") # 结果: 8
带参数的装饰器
可以创建接受参数的装饰器:
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
results = []
for _ in range(n):
results.append(func(*args, **kwargs))
return results
return wrapper
return decorator
@repeat(3)
def greet(name):
return f"Hello, {name}!"
print(greet("张三"))
# ['Hello, 张三!', 'Hello, 张三!', 'Hello, 张三!']
保留原始函数的元数据
装饰器会导致函数元数据丢失,可以使用 functools.wraps
保留:
from functools import wraps
def my_decorator(func):
@wraps(func) # 保留被装饰函数的元数据
def wrapper(*args, **kwargs):
"""包装函数的文档字符串"""
print("Calling decorated function")
return func(*args, **kwargs)
return wrapper
@my_decorator
def example():
"""这是example函数的文档字符串"""
print("Inside example function")
# 查看函数属性
print(example.__name__) # 输出 "example",而不是 "wrapper"
print(example.__doc__) # 输出 "这是example函数的文档字符串"
类方法装饰器
可以装饰类方法:
def log_method_calls(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
print(f"调用方法 {func.__name__}")
return func(self, *args, **kwargs)
return wrapper
class MyClass:
@log_method_calls
def method1(self):
return "方法1的结果"
@log_method_calls
def method2(self, x):
return f"方法2的结果: {x}"
obj = MyClass()
print(obj.method1()) # 调用方法 method1 \n 方法1的结果
print(obj.method2(42)) # 调用方法 method2 \n 方法2的结果: 42
内置装饰器
Python提供了几个内置的装饰器:
@property
将方法转换为只读属性:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
"""获取半径"""
return self._radius
@property
def area(self):
"""计算面积"""
import math
return math.pi * self._radius ** 2
@property
def diameter(self):
"""计算直径"""
return 2 * self._radius
circle = Circle(5)
print(circle.radius) # 5
print(circle.area) # 78.53981633974483
print(circle.diameter) # 10
# circle.radius = 10 # 这会引发AttributeError,因为是只读属性
@classmethod
定义类方法,接受类作为第一个参数:
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@classmethod
def from_string(cls, date_string):
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day)
@classmethod
def today(cls):
from datetime import date
today = date.today()
return cls(today.year, today.month, today.day)
def __str__(self):
return f"{self.year}-{self.month:02d}-{self.day:02d}"
# 使用类方法创建实例
date1 = Date.from_string('2023-02-15')
print(date1) # 2023-02-15
date2 = Date.today()
print(date2) # 当前日期,如 2023-11-07
@staticmethod
定义静态方法,不接受特殊的第一个参数:
class MathUtil:
@staticmethod
def is_prime(n):
"""检查一个数是否为素数"""
if n <= 1:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
@staticmethod
def gcd(a, b):
"""计算最大公约数"""
while b:
a, b = b, a % b
return a
# 使用静态方法
print(MathUtil.is_prime(17)) # True
print(MathUtil.gcd(48, 18)) # 6
常见装饰器模式
计时装饰器
import time
from functools import wraps
def timing_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} 运行时间: {end_time - start_time:.6f} 秒")
return result
return wrapper
@timing_decorator
def slow_function():
"""一个耗时的函数"""
time.sleep(1)
return "完成"
print(slow_function()) # slow_function 运行时间: 1.000123 秒 \n 完成
缓存装饰器
from functools import wraps
def memoize(func):
cache = {}
@wraps(func)
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def fibonacci(n):
"""计算斐波那契数列第n项"""
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(35)) # 快速计算,避免重复计算
参数验证装饰器
from functools import wraps
def validate_args(func):
@wraps(func)
def wrapper(*args, **kwargs):
if len(args) == 0:
raise ValueError("至少需要一个参数")
for arg in args:
if arg < 0:
raise ValueError("参数必须为非负数")
return func(*args, **kwargs)
return wrapper
@validate_args
def calculate_average(numbers):
"""计算平均值"""
return sum(numbers) / len(numbers)
try:
print(calculate_average([1, 2, 3, 4])) # 2.5
print(calculate_average([])) # 引发ValueError
print(calculate_average([-1, 2, 3])) # 引发ValueError
except ValueError as e:
print(f"错误: {e}")
日志装饰器
import logging
from functools import wraps
logging.basicConfig(level=logging.INFO)
def log(func):
@wraps(func)
def wrapper(*args, **kwargs):
logging.info(f"调用: {func.__name__}")
try:
result = func(*args, **kwargs)
logging.info(f"{func.__name__} 返回: {result}")
return result
except Exception as e:
logging.error(f"{func.__name__} 错误: {e}")
raise
return wrapper
@log
def divide(a, b):
"""除法函数"""
return a / b
divide(10, 2) # 记录成功调用
try:
divide(10, 0) # 记录错误
except ZeroDivisionError:
pass
类装饰器
可以使用函数装饰整个类:
def singleton(cls):
"""一个简单的单例装饰器"""
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class Database:
def __init__(self):
self.connection = "Connected"
print("数据库连接创建")
def query(self, sql):
return f"执行SQL: {sql}"
# 只创建一个实例
db1 = Database() # 输出: 数据库连接创建
db2 = Database() # 没有输出,因为没有新建实例
print(db1 is db2) # True, 是同一个实例
单例模式
单例是一种设计模式,确保一个类只有一个实例,并提供全局访问点。
使用装饰器实现单例
上面已经展示了一个基本示例。
使用__new__实现单例
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, name="Default"):
# 注意:__init__每次实例化都会调用
self.name = name
# 测试
s1 = Singleton("First")
s2 = Singleton("Second")
print(s1 is s2) # True
print(s1.name) # "Second" (被最后一次调用覆盖)
使用元类实现单例
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Logger(metaclass=SingletonMeta):
def __init__(self):
self.logs = []
def log(self, message):
self.logs.append(message)
def get_logs(self):
return self.logs
# 测试
logger1 = Logger()
logger1.log("第一条日志")
logger2 = Logger()
logger2.log("第二条日志")
print(logger1 is logger2) # True
print(logger1.get_logs()) # ['第一条日志', '第二条日志']
惰性加载单例模式
class LazySingleton:
__instance = None
def __init__(self):
if not LazySingleton.__instance:
print("初始化单例")
else:
print("单例已存在")
@classmethod
def get_instance(cls):
if not cls.__instance:
cls.__instance = LazySingleton()
return cls.__instance
# 还没有创建实例
s1 = LazySingleton.get_instance() # 初始化单例
s2 = LazySingleton.get_instance() # 单例已存在
print(s1 is s2) # True
线程安全单例模式
import threading
class ThreadSafeSingleton:
_instance = None
_lock = threading.Lock()
def __new__(cls):
with cls._lock:
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
pass
def create_singleton():
singleton = ThreadSafeSingleton()
print(f"创建实例: {id(singleton)}")
# 创建多个线程
threads = []
for _ in range(5):
thread = threading.Thread(target=create_singleton)
threads.append(thread)
# 启动所有线程
for thread in threads:
thread.start()
# 等待所有线程完成
for thread in threads:
thread.join()
# 所有ID应该相同
单例模式的应用场景
- 日志管理器: 确保整个应用程序使用一个日志实例
- 数据库连接: 维护单一的数据库连接
- 配置管理: 加载和提供应用程序配置
- 缓存: 实现应用程序级缓存
- 线程池: 管理一组预先分配的线程
# 配置管理单例示例
class AppConfig:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance._load_config()
return cls._instance
def _load_config(self):
"""加载配置(示例)"""
self.settings = {
"debug": True,
"api_key": "sample_key",
"max_connections": 100
}
def get(self, key, default=None):
"""获取配置项"""
return self.settings.get(key, default)
# 使用
config = AppConfig()
debug_mode = config.get("debug")
api_key = config.get("api_key")
# 在应用的另一部分获取相同的实例
other_config = AppConfig()
print(config is other_config) # True
单例模式的优缺点
优点:
- 保证一个类只有一个实例
- 提供对该实例的全局访问点
- 控制共享资源的并发访问
缺点:
- 单例模式可能使代码紧密耦合
- 在多线程环境下可能需要额外同步
- 可能使单元测试变得困难