Pandas快速入门——基础速览

『AI先锋杯·14天征文挑战第6期』 10w+人浏览 246人参与

Pandas 是 Python 里最常用的数据分析工具库之一,适合做数据清洗、数据统计、表格处理等工作。

文章记录的只是 部分基础和常用命令,如需深入学习了解,可以移步pandas 官方文档


目录

1. Pandas 简介

2. 核心数据结构

2.1 Series

2.1.1 Series的创建

2.1.2 Series的常用属性

2.1.3 Series的常用函数方法

2.1.4 Series的布尔索引

2.1.5 Series的运算

2.2 DataFrame

2.2.1 DataFrame的创建

2.2.2 DataFrame的基本属性

2.2.3 Dataframe的常用函数方法

3. 数据读取与保存

4. 基础操作

4.1 数据选取

4.2 条件筛选

4.3 排序

4.4 去重

5. 缺失值处理

6. 常见统计函数

7. 分组与聚合

8. 时间序列处理

9. 进阶操作


1. Pandas 简介

  • pandas 是基于 NumPy 的数据分析库。
  • pands的英文全称pannel data(面板数据)
  • 核心数据结构:
    • Series:一维数据,类似一列。
    • DataFrame:二维表格,类似 Excel。
  • 常用于:
    • 读写数据(csv、excel、sql、json等)。
    • 数据清洗(缺失值、重复值、数据替换)。
    • 数据筛选与过滤。
    • 分组统计与聚合。
    • 时间序列分析。
  • 特别适合处理结构化数据,如表格类型的数据(类似Excel的表格,关系型数据库SQL)

2. 核心数据结构

2.1 Series

2.1.1 Series的创建

如图左侧为Series Index,代表索引

A为Series Name,代表名字

下边空行为Series Values,代表代表值

一维带标签的数组,可以看成是 索引 + 值

import pandas as pd

# 创建 Series
s = pd.Series([10, 20, 30], index=['a', 'b', 'c'])
print(s)

输出:

a    10
b    20
c    30
dtype: int64

另外还有两种创建方式:

import pandas as pd

# 创建 Series,同时指定索引和名字
s = pd.Series([10, 20, 30], index=['a', 'b', 'c'], name="鸣潮_Series")

# 通过字典创建 Series
s2 = pd.Series({'无妄者': 60, '鉴心': 70, '吟霖': 80}, name="鸣潮角色等级")

常用操作:

  • s.values 取值数组
  • s.index 索引
  • s['a'] 按标签取值
  • s[0] 按位置取值
2.1.2 Series的常用属性
import pandas as pd

# 创建一个 Series
s = pd.Series([10, 20, 30, 40, 50], index=["a", "b", "c", "d", "e"], name="scores")

print("索引:", s.index)
print("值:", s.values)
print("数据类型:", s.dtype)
print("形状:", s.shape)
print("大小:", s.size)
print("维度:", s.ndim)
print("名称:", s.name)
print("是否唯一:", s.is_unique)
print("是否有缺失值:", s.hasnans)
print("内存占用:", s.memory_usage())

输出

索引: Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
值: [10 20 30 40 50]
数据类型: int64
形状: (5,)
大小: 5
维度: 1
名称: scores
是否唯一: True
是否有缺失值: False
内存占用: 148
2.1.3 Series的常用函数方法
import pandas as pd

s = pd.Series([10, 20, 20, None, 40, 50, 50, 50], name="scores")

print("唯一值:", s.unique())
print("唯一值数量:", s.nunique())
print("值频率:\n", s.value_counts())
print("平均值:", s.mean())
print("描述统计:\n", s.describe())
print("是否缺失:\n", s.isnull())
print("填充缺失:\n", s.fillna(0))
print("去重:\n", s.drop_duplicates())
print("排序:\n", s.sort_values(ascending=False))

输出

唯一值: [10. 20. nan 40. 50.]
唯一值数量: 4
值频率:
50.0    3
20.0    2
10.0    1
40.0    1
Name: scores, dtype: int64
平均值: 31.666666666666668
描述统计:
count     7.000000
mean     32.857143
std      15.198684
min      10.000000
25%      20.000000
50%      40.000000
75%      50.000000
max      50.000000
Name: scores, dtype: float64
是否缺失:
0    False
1    False
2    False
3     True
4    False
5    False
6    False
7    False
Name: scores, dtype: bool
填充缺失:
0    10.0
1    20.0
2    20.0
3     0.0
4    40.0
5    50.0
6    50.0
7    50.0
Name: scores, dtype: float64
去重:
0    10.0
1    20.0
3     NaN
4    40.0
5    50.0
Name: scores, dtype: float64
排序:
5    50.0
6    50.0
7    50.0
4    40.0
1    20.0
2    20.0
0    10.0
3     NaN
Name: scores, dtype: float64

2.1.4 Series的布尔索引
import pandas as pd

s = pd.Series([10, 20, 30, 40, 50], index=['a', 'b', 'c', 'd', 'e'])

print("原始数据:\n", s)

# 筛选大于30的元素
print("\n大于30:\n", s[s > 30])

# 筛选等于20的元素
print("\n等于20:\n", s[s == 20])

# 筛选不等于10的元素
print("\n不等于10:\n", s[s != 10])

输出

原始数据:
a    10
b    20
c    30
d    40
e    50
dtype: int64

大于30:
d    40
e    50
dtype: int64

等于20:
b    20
dtype: int64

不等于10:
b    20
c    30
d    40
e    50
dtype: int64

多个条件要用 &(与)|(或)~(非),注意要加括号:

# 大于20 且 小于50
print("\n20 < x < 50:\n", s[(s > 20) & (s < 50)])

# 等于10 或 等于50
print("\n等于10或50:\n", s[(s == 10) | (s == 50)])

# 非大于30
print("\n不是大于30:\n", s[~(s > 30)])
2.1.5 Series的运算

运算类别

示例

说明

示例结果

算术运算

s + 5

每个元素加 5

[15, 25, 35, 45]

s - 2

每个元素减 2

[8, 18, 28, 38]

s * 2

每个元素乘 2

[20, 40, 60, 80]

s / 10

每个元素除以 10

[1.0, 2.0, 3.0, 4.0]

s ** 2

每个元素平方

[100, 400, 900, 1600]

两个 Series 运算

s1 + s2

按索引自动对齐,缺失补 NaN

a:NaN, b:21, c:32, d:NaN

统计运算

s.sum()

求和

100

s.mean()

平均值

25.0

s.max()

最大值

40

s.min()

最小值

10

s.std()

标准差

12.91

逻辑运算

s > 20

大于 20 的元素标记为 True

[False, False, True, True]

s == 30

判断是否等于 30

[False, False, True, False]

s != 40

判断是否不等于 40

[True, True, True, False]

Numpy 函数运算

np.sqrt(s)

逐元素开方

[3.16, 4.47, 5.47, 6.32]

np.exp(s)

指数运算

[2.2e4, 4.8e8, 1.07e13, 2.35e17]

np.sin(s)

正弦运算

[-0.54, 0.91, -0.99, 0.75]


2.2 DataFrame

2.2.1 DataFrame的创建

DataFrame是 Pandas 中最常用的数据结构,类似于 Excel 表格数据库中的数据表

其中:

  • 行(row):用索引(Index)标记。
  • 列(column):用列名(Column Labels)标记。
  • 数据(data):本质上存放在 Numpy 数组中,运算效率高。

可以理解为:
Series = 一维数组(带索引)
DataFrame = 多个 Series 的集合(共享一个行索引)。

二维表格,带行索引和列索引。

data = {
    'name': ['Tom', 'Jerry', 'Spike'],
    'age': [20, 21, 19],
    'score': [90, 85, 88]
}
df = pd.DataFrame(data)
print(df)

输出:

    name  age  score
0    Tom   20     90
1  Jerry   21     85
2  Spike   19     88

常用属性:

  • df.shape 行列数
  • df.columns 列名
  • df.index 行索引
  • df.values 转为数组
2.2.2 DataFrame的基本属性

属性

说明

示例

df.shape

返回 DataFrame 的行数和列数(元组)

(3, 3)

df.index

行索引对象(Index)

RangeIndex(start=0, stop=3, step=1)

df.columns

列索引对象(Index)

Index(['Name','Age','Score'], dtype='object')

df.dtypes

各列数据类型

Name:object, Age:int64, Score:int64

df.values

数据的 Numpy 数组表示

array([...])

df.ndim

维度(一般为 2)

2

df.size

元素总数(行数 × 列数)

9

df.empty

是否为空

False

df.T

转置(行列交换)

见下方示例

df.axes

行索引和列索引列表

[Index([...]), Index([...])]

示例:

import pandas as pd

# 创建 DataFrame
data = {
    "Name": ["Alice", "Bob", "Charlie"],
    "Age": [25, 30, 35],
    "Score": [90, 85, 88]
}
df = pd.DataFrame(data)

print("数据表:\n", df, "\n")
print("形状 shape:", df.shape)
print("行索引 index:", df.index)
print("列索引 columns:", df.columns)
print("数据类型 dtypes:\n", df.dtypes)
print("Numpy 数组 values:\n", df.values)
print("维度 ndim:", df.ndim)
print("元素总数 size:", df.size)
print("是否为空 empty:", df.empty)
print("转置 T:\n", df.T)
print("axes (行索引和列索引):\n", df.axes)

输出:

数据表:
      Name  Age  Score
0    Alice   25     90
1      Bob   30     85
2  Charlie   35     88 

形状 shape: (3, 3)
行索引 index: RangeIndex(start=0, stop=3, step=1)
列索引 columns: Index(['Name', 'Age', 'Score'], dtype='object')
数据类型 dtypes:
Name     object
Age       int64
Score     int64
dtype: object
Numpy 数组 values:
[['Alice' 25 90]
 ['Bob' 30 85]
 ['Charlie' 35 88]]
维度 ndim: 2
元素总数 size: 9
是否为空 empty: False
转置 T:
             0    1        2
Name     Alice  Bob  Charlie
Age         25   30       35
Score       90   85       88
axes (行索引和列索引):
[RangeIndex(start=0, stop=3, step=1), Index(['Name', 'Age', 'Score'], dtype='object')]
2.2.3 Dataframe的常用函数方法

数据查看方法:

方法

说明

示例

df.head(n)

查看前 n 行(默认 5)

df.head(3)

df.tail(n)

查看后 n 行

df.tail(2)

df.info()

查看基本信息(行数、列数、类型、内存)

df.info()

df.describe()

数值列的统计摘要(均值、方差、分位数)

df.describe()

df.sample(n)

随机抽样

df.sample(2)

索引选择方法:

方法

说明

示例

df['col']

选择某一列(返回 Series)

df['Age']

df[['col1','col2']]

选择多列(返回 DataFrame)

df[['Name','Score']]

df.loc[row, col]

按标签选择

df.loc[0, 'Name']

df.iloc[row, col]

按位置选择

df.iloc[1, 2]

df.at[row, col]

快速获取单个值(标签)

df.at[0, 'Age']

df.iat[row, col]

快速获取单个值(位置)

df.iat[1, 2]

数据清洗方法:

方法

说明

示例

df.drop()

删除行或列

df.drop('Age', axis=1)

df.rename()

重命名行或列

df.rename(columns={'Name':'FullName'})

df.fillna()

填充缺失值

df.fillna(0)

df.dropna()

删除缺失值

df.dropna()

df.replace()

替换值

df.replace(90, 100)

df.duplicated()

检测重复行

df.duplicated()

df.drop_duplicates()

删除重复行

df.drop_duplicates()

统计分析方法:

方法

说明

示例

df.sum()

按列求和

df['Score'].sum()

df.mean()

平均值

df['Age'].mean()

df.median()

中位数

df['Score'].median()

df.std()

标准差

df['Score'].std()

df.min()/max()

最小值/最大值

df['Age'].max()

df.value_counts()

统计某列值的频数

df['Name'].value_counts()

df.corr()

各列相关系数矩阵

df.corr()

df.groupby()

按某列分组聚合

df.groupby('Age').mean()

df.pivot_table()

透视表

df.pivot_table(values='Score', index='Age')

示例

import pandas as pd

data = {
    "Name": ["Alice", "Bob", "Charlie", "Alice"],
    "Age": [25, 30, 35, 25],
    "Score": [90, 85, 88, None]
}
df = pd.DataFrame(data)

print("前两行:\n", df.head(2))
print("信息:\n"); df.info()
print("描述:\n", df.describe())

# 索引选择
print("选择列 Name:\n", df['Name'])
print("iloc 选择:\n", df.iloc[0, 1])

# 数据清洗
print("填充缺失值:\n", df.fillna(0))
print("去重:\n", df.drop_duplicates())

# 统计分析
print("平均分:", df['Score'].mean())
print("按 Age 分组平均分:\n", df.groupby('Age')['Score'].mean())

输出


前两行:
    Name  Age  Score
0  Alice   25   90.0
1    Bob   30   85.0

信息:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   Name    4 non-null      object 
 1   Age     4 non-null      int64  
 2   Score   3 non-null      float64
dtypes: float64(1), int64(1), object(1)
memory usage: 228.0+ bytes

描述:
             Age      Score
count   4.000000   3.000000
mean   28.750000  87.666667
std     4.787136   2.516611
min    25.000000  85.000000
25%    25.000000  86.500000
50%    27.500000  88.000000
75%    31.250000  89.000000
max    35.000000  90.000000

选择列 Name:
0      Alice
1        Bob
2    Charlie
3      Alice
Name: Name, dtype: object

iloc 选择:
25

填充缺失值:
      Name  Age  Score
0    Alice   25   90.0
1      Bob   30   85.0
2  Charlie   35   88.0
3    Alice   25    0.0

去重:
      Name  Age  Score
0    Alice   25   90.0
1      Bob   30   85.0
2  Charlie   35   88.0
3    Alice   25    NaN

平均分: 87.66666666666667

按 Age 分组平均分:
Age
25    90.0
30    85.0
35    88.0
Name: Score, dtype: float64

3. 数据读取与保存

  • 读取数据
pd.read_csv('data.csv')        # 读取 CSV
pd.read_excel('data.xlsx')     # 读取 Excel
pd.read_json('data.json')      # 读取 JSON
  • 保存数据
df.to_csv('out.csv', index=False)  
df.to_excel('out.xlsx', index=False)  

4. 基础操作

4.1 数据选取

df['age']        # 取一列
df[['name','age']]  # 取多列
df.loc[0]        # 按行标签
df.iloc[0]       # 按行位置

4.2 条件筛选

df[df['age'] > 20]
df[(df['age'] > 20) & (df['score'] > 85)]

4.3 排序

df.sort_values('score', ascending=False)

4.4 去重

df.drop_duplicates(subset=['name'])

5. 缺失值处理

df.dropna()                 # 删除缺失值
df.fillna(0)                # 填充缺失值
df['age'].fillna(df['age'].mean())  # 用平均值填充

6. 常见统计函数

  • df.describe() 快速统计
  • df.mean() 平均值
  • df.sum() 求和
  • df.min() / df.max()
  • df.count() 非空数量
  • df.value_counts() 计数

7. 分组与聚合

df.groupby('age')['score'].mean()  # 按年龄分组求平均
df.groupby('age').agg({'score':'max','age':'count'})

8. 时间序列处理

dates = pd.date_range('2025-01-01', periods=6, freq='D')
ts = pd.Series([1,2,3,4,5,6], index=dates)
print(ts['2025-01-03':'2025-01-05'])

9. 进阶操作

  • 合并与连接
pd.concat([df1, df2])  # 行拼接
pd.merge(df1, df2, on='key')  # 按某列合并
  • 透视表
df.pivot_table(values='score', index='age', aggfunc='mean')
# ================== Python模块导入完整示例文件 ================== # 本文件完整演示模块导入机制,包含详细注释和多个实际应用示例 # 每个概念和代码块都有中文注释说明 #py -m pip install pandas # ================== 第一部分:模块导入基础概念 ================== """ 📚 什么是模块? 模块就是一个.py文件,里面包含Python代码(变量、函数、类) 就像工具箱里的不同工具,每个模块提供特定功能 🔧 为什么要用模块? 1. 代码复用:写一次功能,多处使用 2. 组织代码:把大项目拆分成小模块 3. 命名空间:避免命名冲突 4. 功能扩展:使用他人写好的强大功能 🎯 导入模块的三种基本方式: 1. import 模块名 → 导入整个模块 2. from 模块 import 名称 → 导入特定功能 3. import 模块 as 别名 → 导入并给模块起别名 """ # ================== 第二部分:基础导入方法 ================== # === 示例1:导入整个模块 === # 导入math模块进行数学计算 import math # 导入整个math模块 # 计算圆的面积(几何测试常用) radius = 5 area = math.pi * math.pow(radius, 2) # 使用模块中的常量和函数 print(f"半径5的圆面积: {area:.2f}") # 输出: 半径5的圆面积: 78.54 # 生成随机测试数据 import random # 导入random模块 def generate_test_users(count): """生成随机用户数据""" users = [] for i in range(count): user_id = random.randint(1000, 9999) age = random.randint(18, 65) users.append(f"用户{user_id}-{age}岁") return users print("随机用户:", generate_test_users(3)) # 导入os模块管理文件 import os # 导入操作系统模块 def get_current_path_info(): """获取当前路径信息""" return { "当前路径": os.getcwd(), "路径是否存在": os.path.exists("test.txt"), "路径类型": "文件" if os.path.isfile("test.txt") else "目录" if os.path.isdir("test.txt") else "不存在" } print("路径信息:", get_current_path_info()) # === 示例2:精准导入特定功能 === # 导入datetime模块的特定类 from datetime import datetime, timedelta # 导入多个类 # 计算测试结束时间 start = datetime.now() end = start + timedelta(hours=2) # 测试时长2小时 print(f"测试开始: {start.strftime('%H:%M')}") print(f"计划结束: {end.strftime('%H:%M')}") # 导入statistics模块的特定函数 from statistics import mean, median # 导入多个函数 # 分析测试结果 test_scores = [85, 92, 78, 90, 88] print(f"平均分: {mean(test_scores)}") print(f"中位数: {median(test_scores)}") # 导入os.path模块特定功能 from os.path import join, basename # 导入路径操作函数 def create_file_path(): """创建文件路径""" path = join("/home/user", "test", "results.csv") return { "完整路径": path, "文件名": basename(path) } print("路径操作:", create_file_path()) # === 示例3:别名导入 === # 导入numpy并起别名 import numpy as np # 科学计算库别名 # 创建测试用数组 test_array = np.array([1, 2, 3, 4, 5]) print(f"数组平均值: {np.mean(test_array)}") # 输出: 3.0 # 导入matplotlib.pyplot并起别名 import matplotlib.pyplot as plt # 图形库别名 # 绘制测试结果趋势图(不保存文件) plt.plot([1, 2, 3], [85, 92, 78]) # 使用别名 plt.title("测试分数趋势") plt.xlabel("测试次数") plt.ylabel("分数") # plt.show() # 注释掉以免自动执行 # 导入pandas并起别名 import pandas as pd # 数据分析库别名 def create_test_dataframe(): """创建测试数据框""" data = { "测试项": ["登录", "注册", "支付"], "通过率": [95, 88, 92] } return pd.DataFrame(data) print("测试数据框:") print(create_test_dataframe()) # ================== 第三部分:高级导入技巧 ================== # === 示例4:条件导入(环境适配) === import sys # 系统模块 # 根据操作系统选择不同模块 if sys.platform == 'win32': import winreg # Windows注册表模块 def get_windows_version(): """获取Windows版本信息""" key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows NT\CurrentVersion") return winreg.QueryValueEx(key, "CurrentVersion")[0] print("Windows版本:", get_windows_version()) else: import pwd # Unix用户信息模块 def get_unix_users(): """获取Unix系统用户列表""" return [user.pw_name for user in pwd.getpwall()] print("Unix用户:", get_unix_users()) # 根据Python版本选择不同模块 import platform # 平台信息模块 if platform.python_version_tuple()[0] == '3': from urllib.request import urlopen # Python3网络请求 else: from urllib2 import urlopen # Python2网络请求 # 根据需求选择不同实现 def select_implementation(): """根据需求选择不同实现""" import os if os.name == 'posix': from subprocess import Popen as Process else: from subprocess import Popen as Process return Process print("选中的实现:", select_implementation().__name__) # === 示例5:延迟导入(按需加载) === def generate_test_data(): """延迟导入Faker模块(内存优化)""" from faker import Faker fake = Faker('zh_CN') return { "姓名": fake.name(), "邮箱": fake.email() } print("延迟生成测试数据:", generate_test_data()) def run_performance_test(): """延迟导入time模块(按需使用)""" import time start = time.time() time.sleep(0.5) # 模拟耗时操作 return time.time() - start print(f"性能测试耗时: {run_performance_test():.3f}秒") def use_logging(): """延迟导入logging模块(按需使用)""" import logging logging.basicConfig(level=logging.INFO) logging.info("测试日志信息") use_logging() # === 示例6:模块重载(开发调试) === import importlib # 导入重载工具 import my_module # 自定义模块 # 第一次使用 print("初始版本:", my_module.calculate(10)) # 修改my_module.py后... importlib.reload(my_module) # 强制重载模块 # 使用更新后的函数 print("更新后版本:", my_module.calculate(10)) # 重载带状态的模块 def test_reload_with_state(): """测试带状态的模块重载""" import my_module_with_state as mws print("初始状态:", mws.get_state()) mws.update_state(100) print("更新状态:", mws.get_state()) importlib.reload(mws) print("重载后状态:", mws.get_state()) test_reload_with_state() # ================== 第四部分:实际应用场景 ================== # === 示例7:测试数据生成 === def generate_test_users(count): """生成随机用户数据(自动化测试常用)""" from faker import Faker fake = Faker('zh_CN') return [{ "name": fake.name(), "email": fake.email(), "address": fake.address() } for _ in range(count)] print("生成的测试用户:", generate_test_users(3)) def generate_test_orders(count): """生成测试订单数据(电商测试常用)""" from faker import Faker fake = Faker() return [{ "order_id": fake.uuid4(), "amount": round(random.uniform(10, 1000), 2), "date": fake.date() } for _ in range(count)] print("生成的测试订单:", generate_test_orders(2)) def generate_test_logs(count): """生成测试日志数据(日志分析常用)""" from faker import Faker fake = Faker() return [{ "timestamp": fake.date_time_this_year(), "level": random.choice(["INFO", "WARNING", "ERROR"]), "message": fake.sentence() } for _ in range(count)] print("生成的测试日志:", generate_test_logs(3)) # === 示例8:性能测试计时 === def measure_performance(func): """测量函数执行时间(性能测试框架常用)""" import time start = time.perf_counter() result = func() duration = time.perf_counter() - start print(f"⏱️ 函数执行耗时: {duration:.4f}秒") return result def sample_function(): """被测函数""" time.sleep(0.3) # 模拟耗时操作 return "完成" print("性能测试结果:", measure_performance(sample_function)) def run_test_cases(cases): """批量运行测试用例并计时(测试框架常用)""" import time start = time.time() results = [case() for case in cases] duration = time.time() - start print(f"批量测试耗时: {duration:.3f}秒") return results print("批量测试结果:", run_test_cases([sample_function, sample_function])) def compare_algorithms(algs, data): """比较不同算法性能(性能分析常用)""" import time results = {} for name, func in algs.items(): start = time.time() func(data) results[name] = time.time() - start return results # === 示例9:配置组合测试 === from itertools import product # 组合生成器 def test_product_configurations(): """测试所有产品配置组合(测试覆盖率保障)""" configs = { "颜色": ["红", "蓝", "绿"], "尺寸": ["S", "M", "L"], "材质": ["棉", "涤纶"] } all_combinations = list(product(*configs.values())) results = [] for i, combo in enumerate(all_combinations, 1): print(f"测试组合 {i}: {combo}") results.append("通过" if random.random() > 0.2 else "失败") return results print("产品配置测试结果:", test_product_configurations()) def test_api_parameters(): """测试API参数组合(接口测试常用)""" from itertools import product params = { "format": ["json", "xml"], "version": ["v1", "v2"], "auth": [True, False] } combinations = list(product(*params.values())) print(f"共需测试 {len(combinations)} 种API参数组合") for i, combo in enumerate(combinations, 1): print(f"测试参数组合 {i}: {combo}") test_api_parameters() def test_ui_combinations(): """测试UI元素组合(前端测试常用)""" from itertools import product elements = { "主题": ["暗色", "亮色"], "分辨率": ["1080p", "4K"], "浏器": ["Chrome", "Firefox", "Safari"] } combinations = list(product(*elements.values())) print(f"共需测试 {len(combinations)} 种UI组合") for i, combo in enumerate(combinations, 1): print(f"测试UI组合 {i}: {combo}") test_ui_combinations() # ================== 第五部分:最佳实践与常见问题 ================== """ ✅ 模块导入最佳实践: 1. 导入顺序: a. 标准库模块 (import os) b. 第三方库模块 (import numpy) c. 自定义模块 (from myapp import utils) 2. 每行一个导入(PEP8规范): import os import sys import pandas as pd 3. 避免通配符导入: # 不推荐 from math import * # 推荐 from math import sqrt, pi 4. 使用别名解决冲突: import myapp.utils as app_utils import thirdparty.utils as tp_utils 5. 大型项目使用包结构: from myproject.core import database from myproject.tests import test_utils 🚫 常见问题与解决方案: 1. ModuleNotFoundError: 模块未找到 - 检查拼写错误 - 确保模块已安装 (pip install 模块名) - 检查PYTHONPATH环境变量 2. ImportError: 导入错误 - 检查模块中是否存在该名称 - 使用dir(模块)查看可用名称 - 检查循环导入问题 3. 循环导入问题: # 模块A.py import B # 同时B.py又import A 解决方案: a. 重构代码结构 b. 将导入移到函数内部 c. 使用importlib延迟导入 4. 模块缓存问题: - Python会缓存导入的模块 - 开发时使用importlib.reload()强制刷新 - 生产环境不需要刷新 5. 版本冲突: - 使用虚拟环境隔离项目 - 使用requirements.txt管理依赖 - 检查模块文档确认兼容性 """ # ================== 第六部分:综合练习 ================== """ 📚 课程总(总) 本课程专为测试工程师设计,系统讲解Python两大核心模块: 1. requests库:HTTP请求库,用于API测试 2. logging模块:日志记录工具,用于测试过程跟踪 通过本课程,您将掌握: - 使用requests发送各种HTTP请求 - 处理API响应和异常 - 配置专业的测试日志系统 - 结合两者实现完整的API测试工作流 """ # ================== 第一部分:requests库入门 ================== """ 📌 什么是requests库? requests是Python最流行的HTTP客户端库,提供简洁API发送HTTP请求。 测试工程师使用它进行: - API接口测试 - 数据获取与验证 - 服务状态监控 """ # === 基础GET请求示例 === import requests # 导入requests模块 def test_get_request(): """测试GET请求基本用法""" # 发送GET请求 response = requests.get("https://jsonplaceholder.typicode.com/users") # 检查响应状态码(200表示成功) if response.status_code == 200: print("✅ GET请求成功!") # 获取JSON格式响应数据 users = response.json() print(f"获取到 {len(users)} 个用户数据") print(f"第一个用户: {users[0]['name']}") else: print(f"❌ 请求失败,状态码: {response.status_code}") # 查看完整响应信息 print("\n=== 响应详情 ===") print(f"状态码: {response.status_code}") print(f"响应头: {response.headers['Content-Type']}") print(f"响应时间: {response.elapsed.total_seconds():.2f}秒") # 执行GET请求测试 print("\n" + "=" * 50) print("GET请求测试") test_get_request() # === 带参数的GET请求 === def test_get_with_params(): """测试带查询参数的GET请求""" # 设置查询参数 params = { "userId": 1, "_limit": 3 # 限制返回结果数量 } response = requests.get( "https://jsonplaceholder.typicode.com/posts", params=params ) print("\n=== 带参数请求结果 ===") print(f"请求URL: {response.url}") print(f"获取到 {len(response.json())} 篇帖子") # 执行带参数请求测试 print("\n" + "=" * 50) print("带参数的GET请求测试") test_get_with_params() # === POST请求提交数据 === def test_post_request(): """测试POST请求提交数据""" # 准备测试数据 new_post = { "title": "API测试文章", "body": "这是通过requests提交的测试内容", "userId": 1 } # 发送POST请求 response = requests.post( "https://jsonplaceholder.typicode.com/posts", json=new_post # 自动编码为JSON ) print("\n=== POST请求结果 ===") if response.status_code == 201: # 201表示创建成功 print("✅ 创建资源成功!") created_post = response.json() print(f"创建的资源ID: {created_post['id']}") print(f"服务器返回内容: {created_post}") else: print(f"❌ 创建失败,状态码: {response.status_code}") # 执行POST请求测试 print("\n" + "=" * 50) print("POST请求测试") test_post_request() # === 异常处理 === def test_request_errors(): """测试请求异常处理""" try: # 测试超时(设置0.001秒故意触发超时) response = requests.get( "https://jsonplaceholder.typicode.com/users", timeout=0.001 ) except requests.exceptions.Timeout: print("\n=== 超时异常 ===") print("⚠️ 请求超时!请检查网络或增加超时时间") try: # 测试无效URL response = requests.get("https://invalid-domain-12345.com") except requests.exceptions.ConnectionError: print("\n=== 连接异常 ===") print("⚠️ 连接失败!请检查URL是否正确或网络是否可用") # 执行异常处理测试 print("\n" + "=" * 50) print("异常处理测试") test_request_errors() # ================== 第二部分:logging模块使用 ================== """ 📌 什么是logging模块? logging是Python标准日志库,提供灵活的分级日志系统。 测试工程师使用它: - 记录测试步骤和结果 - 追踪测试过程 - 分析测试失败原因 - 生成测试报告 """ # === 基础日志配置 === import logging # 导入logging模块 def setup_basic_logger(): """配置基础日志记录器""" # 基础配置(输出到控制台) logging.basicConfig( level=logging.INFO, # 设置日志级别为INFO format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) # 创建日志记录器 logger = logging.getLogger("API测试日志") logger.info("=== 基础日志配置完成 ===") return logger # 初始化基础日志 print("\n" + "=" * 50) print("基础日志配置测试") basic_logger = setup_basic_logger() basic_logger.info("这是一条INFO级别日志") basic_logger.warning("这是一条WARNING级别日志") # === 文件日志配置 === def setup_file_logger(): """配置文件日志记录器""" # 创建高级日志记录器 logger = logging.getLogger("文件日志") logger.setLevel(logging.DEBUG) # 设置更详细的日志级别 # 创建文件处理器(每天生成一个日志文件,保留7天) from logging.handlers import TimedRotatingFileHandler file_handler = TimedRotatingFileHandler( filename='api_tests.log', # 日志文件名 when='midnight', # 每天午夜切割 backupCount=7 # 保留7个备份 ) # 设置文件日志格式 file_format = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) file_handler.setFormatter(file_format) # 添加到记录器 logger.addHandler(file_handler) logger.info("=== 文件日志配置完成 ===") return logger # 初始化文件日志 print("\n" + "=" * 50) print("文件日志配置测试") file_logger = setup_file_logger() file_logger.debug("详细调试信息") file_logger.info("测试步骤记录") file_logger.error("模拟错误信息") # === 日志级别实践 === def log_level_demo(): """演示不同日志级别使用场景""" logger = logging.getLogger("日志级别演示") # 不同场景使用不同级别 logger.debug("详细调试信息(开发阶段使用)") logger.info("测试步骤开始:用户登录") logger.warning("非关键问题:头像图片未加载") logger.error("关键错误:支付接口返回500错误") logger.critical("致命错误:数据库连接失败") # 执行日志级别演示 print("\n" + "=" * 50) print("日志级别演示") log_level_demo() # === 日志捕获异常 === def log_exception_demo(): """演示如何记录异常信息""" logger = logging.getLogger("异常日志") try: # 模拟可能出错的代码 result = 1 / 0 except Exception as e: logger.error("发生数学运算错误", exc_info=True) logger.exception("完整异常追踪:") # 执行异常日志演示 print("\n" + "=" * 50) print("异常日志演示") log_exception_demo() # ================== 第三部分:综合应用 ================== """ 🚀 requests + logging 综合应用 结合两个模块实现完整的API测试工作流: 1. 使用requests发送API请求 2. 使用logging记录测试过程 3. 验证响应并记录结果 """ def api_test_workflow(): """API测试工作流(带完整日志)""" # 创建专用日志记录器 logger = logging.getLogger("API测试工作流") logger.setLevel(logging.INFO) # 添加控制台处理器 console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter('%(levelname)s - %(message)s')) logger.addHandler(console_handler) # 开始测试流程 logger.info("=" * 50) logger.info("开始API测试工作流") # 步骤1: 用户登录 logger.info("步骤1: 用户登录") try: login_data = {"username": "testuser", "password": "testpass"} login_response = requests.post( "https://api.example.com/login", json=login_data, timeout=5 ) if login_response.status_code == 200: token = login_response.json().get("token") logger.info(f"✅ 登录成功,获取token: {token[:8]}...") else: logger.error(f"❌ 登录失败,状态码: {login_response.status_code}") return except Exception as e: logger.exception("登录请求异常") return # 步骤2: 获取用户信息 logger.info("步骤2: 获取用户信息") try: headers = {"Authorization": f"Bearer {token}"} user_response = requests.get( "https://api.example.com/user/me", headers=headers, timeout=5 ) if user_response.status_code == 200: user_data = user_response.json() logger.info(f"✅ 获取用户信息: {user_data['username']}") else: logger.error(f"❌ 获取用户信息失败,状态码: {user_response.status_code}") except Exception as e: logger.exception("获取用户信息异常") # 步骤3: 创建测试订单 logger.info("步骤3: 创建测试订单") try: order_data = {"product": "测试商品", "quantity": 2, "price": 99.9} order_response = requests.post( "https://api.example.com/orders", json=order_data, headers=headers, timeout=5 ) if order_response.status_code == 201: order_id = order_response.json().get("id") logger.info(f"✅ 创建订单成功,ID: {order_id}") else: logger.error(f"❌ 创建订单失败,状态码: {order_response.status_code}") except Exception as e: logger.exception("创建订单异常") # 测试结果总结 logger.info("=" * 50) logger.info("API测试工作流完成") logger.info("=" * 50) # 执行综合测试 print("\n" + "=" * 50) print("综合应用:API测试工作流") api_test_workflow() # ================== 课程总结 ================== """ 🎯 课程总结 1. requests库核心: - 发送GET/POST等HTTP请求 - 处理参数和JSON数据 - 异常处理和超时控制 2. logging模块核心: - 配置日志级别和格式 - 输出到控制台和文件 - 记录异常和错误信息 3. 综合应用: - 结合requests和logging实现完整测试流程 - 记录关键测试步骤和结果 - 创建可追溯的测试日志 💡 实践建议: 1. 为每个测试用例创建独立的日志记录器 2. 使用不同的日志级别区分信息重要性 3. 在API测试中总是添加超时和异常处理 4. 定期归档和分析测试日志 """ # 注意:实际API测试时替换为真实API端点 # 本示例使用JSONPlaceholder作为测试API # ================== 总结 ================== """ 🎯 模块导入核心要点: 1. 基础导入:三种基本方式满足不同需求 2. 高级技巧:条件导入、延迟导入解决特定问题 3. 包管理:使用__init__.py组织大型项目 4. 最佳实践:遵循PEP8规范,避免常见陷阱 5. 调试技巧:理解导入机制,解决导入错误 📚 下一步学习: 1. 创建自定义模块和包 2. 使用setuptools打包项目 3. 探索Python标准库(os, sys, re等) 4. 学习虚拟环境管理(venv, conda) 5. 掌握第三方库安装(pip, poetry) """ # 注意:本文件中的plt.show()被注释掉以免自动执行 # 实际使用时请取消注释以查看图形输出 这是我的课程文件,现在需要修改下,1.需要有总分总的形式,2.也要讲清楚用import的几种方式,3.讲的例子尽可能是接口测试相关的,或者是测试常用的,每行代码都要有注释
08-25
# Python模块导入与接口测试应用完整指南 ## 总述:模块导入的重要性 模块导入是Python开发中的基础环节,尤其在接口测试中,合理的模块导入可以提高代码的可读性、可维护性以及测试效率。本指南将从模块导入的基础知识讲起,逐步深入到接口测试相关的实际应用,帮助测试工程师更好地理解和使用Python模块导入机制。 --- ## 第一部分:模块导入基础 ### 1.1 import 模块名 —— 导入整个模块 ```python import requests # 导入requests库用于发送HTTP请求 ``` **说明:** - `import requests` 表示导入整个 `requests` 模块。 - 这种方式适用于需要使用模块中多个功能的场景。 **接口测试应用示例:** ```python def send_get_request(): """发送GET请求获取用户列表""" response = requests.get("https://jsonplaceholder.typicode.com/users") print(f"响应状态码: {response.status_code}") print(f"响应内容: {response.json()}") ``` ### 1.2 from 模块 import 名称 —— 导入特定功能 ```python from requests import get # 仅导入get方法 ``` **说明:** - `from requests import get` 表示只从 `requests` 模块中导入 `get` 函数。 - 适用于只使用模块中某个特定功能的场景,减少命名空间污染。 **接口测试应用示例:** ```python def send_get_request(): """发送GET请求获取用户列表""" response = get("https://jsonplaceholder.typicode.com/users") print(f"响应状态码: {response.status_code}") print(f"响应内容: {response.json()}") ``` ### 1.3 import 模块 as 别名 —— 导入并给模块起别名 ```python import requests as req # 给requests起别名req ``` **说明:** - `import requests as req` 表示将 `requests` 模块简写为 `req`。 - 适用于模块名较长或容易与其他模块名冲突的场景。 **接口测试应用示例:** ```python def send_get_request(): """发送GET请求获取用户列表""" response = req.get("https://jsonplaceholder.typicode.com/users") print(f"响应状态码: {response.status_code}") print(f"响应内容: {response.json()}") ``` --- ## 第二部分:高级模块导入技巧 ### 2.1 条件导入(根据环境选择模块) ```python import sys # 导入sys模块用于判断操作系统 if sys.platform == 'win32': import winreg # Windows平台注册表模块 else: import pwd # Unix平台用户信息模块 ``` **说明:** - 根据操作系统平台选择不同的模块导入。 - 适用于跨平台测试脚本中需要调用系统特定功能的场景。 **接口测试应用示例:** ```python def get_user_info(): """根据平台获取用户信息""" if sys.platform == 'win32': import winreg # 获取Windows用户信息(示例) return "Windows用户" else: import pwd return pwd.getpwuid(os.getuid()).pw_name ``` ### 2.2 延迟导入(按需加载模块) ```python def generate_test_data(): """延迟导入Faker模块(按需加载)""" from faker import Faker # 在函数内部导入,减少启动时间 fake = Faker() return { "用户名": fake.user_name(), "邮箱": fake.email() } ``` **说明:** - 在函数内部导入模块,避免程序启动时加载不必要的模块。 - 适用于资源消耗大或不常使用的模块。 **接口测试应用示例:** ```python def run_performance_test(): """延迟导入time模块(按需使用)""" import time start = time.time() time.sleep(0.5) # 模拟耗时操作 return time.time() - start ``` ### 2.3 模块重载(调试时更新模块) ```python import importlib # 导入模块重载工具 import my_module # 导入自定义模块 importlib.reload(my_module) # 重新加载模块 ``` **说明:** - 在开发调试过程中,如果修改了模块内容,可以通过 `importlib.reload()` 重新加载模块。 - 避免重启整个测试脚本。 **接口测试应用示例:** ```python def test_reload(): """测试模块重载功能""" import my_module print("旧版本:", my_module.calculate(10)) importlib.reload(my_module) print("新版本:", my_module.calculate(10)) ``` --- ## 第三部分:模块导入在接口测试中的综合应用 ### 3.1 使用requests进行接口测试 ```python import requests # 导入requests库 def test_api_get(): """测试GET接口""" response = requests.get("https://jsonplaceholder.typicode.com/posts") assert response.status_code == 200, "状态码不为200" data = response.json() print(f"获取到 {len(data)} 条帖子") ``` ### 3.2 使用logging记录测试日志 ```python import logging # 导入日志模块 logging.basicConfig(level=logging.INFO) # 设置日志级别为INFO def test_api_get_with_log(): """带日志的GET接口测试""" logging.info("开始测试GET接口") response = requests.get("https://jsonplaceholder.typicode.com/posts") if response.status_code == 200: logging.info("GET请求成功") else: logging.error(f"GET请求失败,状态码: {response.status_code}") ``` ### 3.3 模块组合使用:requests + logging ```python import requests import logging logging.basicConfig(level=logging.INFO) def api_test(): """综合接口测试流程""" logging.info("开始测试登录接口") response = requests.post("https://api.example.com/login", json={"username": "test", "password": "123456"}) if response.status_code == 200: logging.info("登录成功") token = response.json().get("token") headers = {"Authorization": f"Bearer {token}"} user_response = requests.get("https://api.example.com/user", headers=headers) logging.info(f"用户信息: {user_response.json()}") else: logging.error("登录失败") ``` --- ## 第四部分:模块导入最佳实践与常见问题 ### 4.1 最佳实践 - **导入顺序:** - 标准库模块(如 `os`, `sys`) - 第三方库模块(如 `requests`, `pandas`) - 自定义模块(如 `my_module`) - **避免通配符导入:** - 不推荐:`from math import *` - 推荐:`from math import sqrt, pi` - **使用别名解决命名冲突:** - `import pandas as pd` - **使用模块结构组织代码:** - `from myproject.utils import logger` ### 4.2 常见问题与解决方案 - **ModuleNotFoundError:** - 解决方案:检查拼写、安装模块(`pip install requests`) - **ImportError:** - 解决方案:检查模块是否存在该函数、使用 `dir(module)` 查看可用功能 - **循环导入问题:** - 解决方案:重构代码结构、延迟导入(`import` 放在函数内) - **模块缓存问题:** - 解决方案:使用 `importlib.reload(module)` 强制刷新 --- ## 第五部分:总结 模块导入是构建可维护、可扩展测试脚本的基础。通过 `import`、`from ... import` 和 `import ... as` 三种方式,我们可以灵活地引入所需功能。结合接口测试的实际需求,合理使用模块导入技巧(如条件导入、延迟导入、模块重载),可以显著提升测试效率和代码质量。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值