Skip to main content

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应该相同

单例模式的应用场景

  1. 日志管理器: 确保整个应用程序使用一个日志实例
  2. 数据库连接: 维护单一的数据库连接
  3. 配置管理: 加载和提供应用程序配置
  4. 缓存: 实现应用程序级缓存
  5. 线程池: 管理一组预先分配的线程
# 配置管理单例示例
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

单例模式的优缺点

优点:

  1. 保证一个类只有一个实例
  2. 提供对该实例的全局访问点
  3. 控制共享资源的并发访问

缺点:

  1. 单例模式可能使代码紧密耦合
  2. 在多线程环境下可能需要额外同步
  3. 可能使单元测试变得困难