[python] 代码性能分析工具line_profiler使用指北

news/2025/10/24 20:46:27/文章来源:https://www.cnblogs.com/luohenyueji/p/19164198

代码分析能够评估各部分代码的时间消耗,即进行时间复杂度分析。通过这一过程,我们可以识别影响整体运行效率的关键部分,从而更高效地利用底层计算资源。此外,代码分析也可用于评估内存使用情况,即空间复杂度,以优化内存管理并提升其使用效率。本文主要关注时间复杂度分析的内容。

Python默认提供了两个实用的性能分析库:cProfile和profile。它们能够按函数维度输出性能数据,但无法展示函数内部逐行的执行详情。而Python公开库line_profiler弥补了这一不足,使我们能够清晰查看代码中每一行的执行耗时。

line_profiler是Python中一款强大的逐行性能分析工具,能够帮助开发者精确定位代码中的性能瓶颈。对于初学者而言,该工具在代码优化过程中具有重要价值。line_profiler官方开源仓库见:line_profiler-github,官方文档见:line_profiler-doc。

data

本文将提供一份简单易用的line_profiler教程,重点讲解其在代码中的使用方法;命令行端的使用方式,可参考:Line by Line Profiling of Python Code。line_profiler安装命令如下:

pip install line_profiler

import line_profiler
# 查看line_profiler版本
line_profiler.__version__
'4.1.3'

目录
  • 1 使用入门
    • 1.1 基础使用
    • 1.2 进阶使用
  • 2 参考

1 使用入门

1.1 基础使用

简单调用

以下代码为示例耗时代码,它会经过不同时长的休眠,随后生成大量随机数并计算其平均值。

import time
import math
import randomdef power_sum(a, b):"""计算a到b的平方和"""return sum(math.pow(x, 2) for x in range(a, b))def calculate(sleep_time):time.sleep(sleep_time)# 随机范围计算平方和的平均值start = 0 end = 1000000total = power_sum(start, end)return total / (end - start)def test_func():calculate(sleep_time=1)calculate(sleep_time=3)calculate(sleep_time=5)

使用line_profiler分析函数运行时间,首先创建一个LineProfiler对象,再通过调用该实例并传入目标函数,生成一个分析器。执行该分析器即可自动运行目标函数。函数执行完成后,调用分析器实例的print_stats方法即可输出分析结果。注意:直接调用print_stats仅会显示目标函数中顶层代码的运行时间。

from line_profiler import LineProfilerlprofiler = LineProfiler()
lp_wrapper = lprofiler(test_func)lp_wrapper()
lprofiler.print_stats()
Timer unit: 1e-09 sTotal time: 9.92798 s
File: /tmp/ipykernel_14853/1826372064.py
Function: test_func at line 17Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================17                                           def test_func():18         1 1242792669.0    1e+09     12.5      calculate(sleep_time=1)19         1 3340978413.0    3e+09     33.7      calculate(sleep_time=3)20         1 5344205767.0    5e+09     53.8      calculate(sleep_time=5)

print_stats输出的各列含义如下:

  • Timer unit

    时间单位(默认自动根据代码执行速度调整),常见的有秒(s)、毫秒(ms,1e-3 秒)、微秒(us,1e-6 秒)、纳秒(ns,1e-9 秒)

  • Total time

    整个函数的总执行时间

  • Line #

    代码行号

  • Hits

    该行代码的执行次数(循环体通常次数较多,函数定义、return等语句通常为1次)

  • Time

    该行代码的累计执行时间(单位同Timer unit),包含该行调用的所有函数耗时

  • Per Hit

    每次执行该行代码的平均时间,计算公式为Time / Hits

  • % Time

    该行耗时占函数总时间的百分比,是识别性能瓶颈的关键指标,需重点关注占比较高的行,循环体通常是性能瓶颈所在

  • Line Contents

    代码内容本身

深层调用

使用line_profiler分析函数运行时间时,如需同时分析其调用的下一层或更深层函数,则需在创建LineProfiler对象时明确指定所有待追踪的目标函数及其子函数。此时,line_profiler会为每个被监控的函数分别生成分析报告,且父函数的耗时统计中将包含所有子函数的执行时间。

from line_profiler import LineProfilerlprofiler = LineProfiler()
lprofiler.add_function(calculate)
lprofiler.add_function(power_sum)
lp_wrapper = lprofiler(test_func)lp_wrapper()
# 追踪的函数列表
lprofiler.functions
# output_unit:设置输出单位,可选值,1(秒),1e-3(毫秒),1e-6(微秒)
# details:是否显示详细的行级分析信息,默认是
# summarize:是否对结果进行汇总,默认否
# rich:是否使用富文本格式输出,默认否
lprofiler.print_stats(output_unit=1e-3, details=True, summarize=False, rich=False)
Timer unit: 0.001 sTotal time: 0.756163 s
File: /tmp/ipykernel_14853/1826372064.py
Function: power_sum at line 5Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================5                                           def power_sum(a, b):6                                               """计算a到b的平方和"""7         3        756.2    252.1    100.0      return sum(math.pow(x, 2) for x in range(a, b))Total time: 9.76247 s
File: /tmp/ipykernel_14853/1826372064.py
Function: calculate at line 9Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================9                                           def calculate(sleep_time):10         3       9006.3   3002.1     92.3      time.sleep(sleep_time)11                                               # 随机范围计算平方和的平均值12         3          0.0      0.0      0.0      start = 0 13         3          0.0      0.0      0.0      end = 100000014         3        756.2    252.1      7.7      total = power_sum(start, end)15         3          0.0      0.0      0.0      return total / (end - start)Total time: 9.76259 s
File: /tmp/ipykernel_14853/1826372064.py
Function: test_func at line 17Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================17                                           def test_func():18         1       1250.6   1250.6     12.8      calculate(sleep_time=1)19         1       3253.7   3253.7     33.3      calculate(sleep_time=3)20         1       5258.2   5258.2     53.9      calculate(sleep_time=5)

使用装饰器调用

这种以分析器实例作为装饰器的方式,实质上是一种语法糖。它将被装饰的函数包装为一个代理,使分析器能够监听每次调用,从而精确记录其每一行的执行情况。

from line_profiler import LineProfiler# 创建性能分析器
lprofiler = LineProfiler()# 使用装饰器标记要分析的函数
@lprofiler
def fibonacci(n):if n <= 1:return nreturn fibonacci(n-1) + fibonacci(n-2)# 没有装饰器标记的函数
def run_analysis():result = fibonacci(10)print(f"Fibonacci result: {result}")# 执行并获取分析结果
run_analysis()
lprofiler.print_stats()
Fibonacci result: 55
Timer unit: 1e-09 sTotal time: 0.000116988 s
File: /tmp/ipykernel_14853/2361721755.py
Function: fibonacci at line 7Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================7                                           @lprofiler8                                           def fibonacci(n):9       177      31407.0    177.4     26.8      if n <= 1:10        89      10762.0    120.9      9.2          return n11        88      74819.0    850.2     64.0      return fibonacci(n-1) + fibonacci(n-2)

分析类中的方法

使用line_profiler分析类方法时,需遵循特定流程:首先,必须将目标类的类方法在分析器中显式注册;其次,这些方法必须绑定到具体的类实例上。执行分析时,应通过分析器返回的包装器函数来触发,而非直接调用原始方法,以确保性能数据能被正确捕获。

from line_profiler import LineProfilerclass DataProcessor:def __init__(self, data):self.data = dataself.cache = {}def process_data(self):"""处理数据的主方法"""return [self._process_single_item(item) for item in self.data]def _process_single_item(self, item):"""处理单个数据项"""if item not in self.cache:self.cache[item] = self._complex_calculation(item)return self.cache[item]def _complex_calculation(self, x):"""模拟复杂计算"""return sum((x + i) **2 for i in range(100))# 初始化并分析
processor = DataProcessor(list(range(100)))
lprofiler = LineProfiler(processor.process_data,processor._process_single_item,processor._complex_calculation
)lp_wrapper = lprofiler(processor.process_data)
results = lp_wrapper()print(f"Processed {len(results)} items")
lprofiler.print_stats()
Processed 100 items
Timer unit: 1e-09 sTotal time: 0.00321407 s
File: /tmp/ipykernel_14853/2028146768.py
Function: process_data at line 8Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================8                                               def process_data(self):9                                                   """处理数据的主方法"""10         1    3214073.0    3e+06    100.0          return [self._process_single_item(item) for item in self.data]Total time: 0.00308825 s
File: /tmp/ipykernel_14853/2028146768.py
Function: _process_single_item at line 12Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================12                                               def _process_single_item(self, item):13                                                   """处理单个数据项"""14       100      19064.0    190.6      0.6          if item not in self.cache:15       100    3049582.0  30495.8     98.7              self.cache[item] = self._complex_calculation(item)16       100      19599.0    196.0      0.6          return self.cache[item]Total time: 0.00296471 s
File: /tmp/ipykernel_14853/2028146768.py
Function: _complex_calculation at line 18Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================18                                               def _complex_calculation(self, x):19                                                   """模拟复杂计算"""20       100    2964705.0  29647.0    100.0          return sum((x + i) **2 for i in range(100))

使用上下文管理器控制分析范围

from line_profiler import LineProfilerdef expensive_operation(n):"""昂贵的操作"""result = 0for i in range(n):# 模拟CPU密集型工作for j in range(1000):result += (i * j) % (n + 1)return resultdef quick_operation(data):"""快速操作"""return [x * 2 for x in data]lprofiler = LineProfiler(expensive_operation)  # 直接在初始化时指定要分析的函数
# 使用with语句启动性能分析上下文,仅对该上下文中的代码进行分析
with lprofiler:result1 = expensive_operation(1000)print(f"Expensive operation result: {result1}")# 不分析的快速操作
print(f"Quick operation result: {quick_operation(range(10))}")lprofiler.print_stats()
Expensive operation result: 497084589
Quick operation result: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Timer unit: 1e-09 sTotal time: 0.379707 s
File: /tmp/ipykernel_14853/795522087.py
Function: expensive_operation at line 3Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================3                                           def expensive_operation(n):4                                               """昂贵的操作"""5         1        512.0    512.0      0.0      result = 06      1001     164615.0    164.5      0.0      for i in range(n):7                                                   # 模拟CPU密集型工作8   1001000  145481901.0    145.3     38.3          for j in range(1000):9   1000000  234060120.0    234.1     61.6              result += (i * j) % (n + 1)10         1        242.0    242.0      0.0      return result

手动控制调用与结果保存

在手动控制模式下,LineProfiler类的enable_by_count与disable_by_count方法分别用于启动和终止性能计数,显式调用二者可直接对中间代码段进行性能分析;因无需依赖包装函数,能更灵活地控制分析范围。

from line_profiler import LineProfiler
import time
import math# 创建一个示例模块的函数
def process_data(n):"""模拟一个需要性能分析的函数"""result = 0# 模拟一些计算密集型操作for i in range(n):result += math.sqrt(i) * math.sin(i)time.sleep(0.1)return result# 创建分析器实例
lprofiler = LineProfiler()# 添加要分析的函数
lprofiler.add_function(process_data)# 运行分析
print("开始性能分析...")lprofiler.enable_by_count()
result = process_data(100)
lprofiler.disable_by_count()print(f"函数结果: {result}")# 使用with open保存结果到文件
with open('profile_results.txt', 'w', encoding='utf-8') as f:lprofiler.print_stats(f)print("\n=== 控制台输出分析结果 ===")
lprofiler.print_stats()
开始性能分析...
函数结果: -4.787834159955427=== 控制台输出分析结果 ===
Timer unit: 1e-09 sTotal time: 0.100183 s
File: /tmp/ipykernel_14853/4142849225.py
Function: process_data at line 6Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================6                                           def process_data(n):7                                               """模拟一个需要性能分析的函数"""8         1        388.0    388.0      0.0      result = 09                                               10                                               # 模拟一些计算密集型操作11       101      16515.0    163.5      0.0      for i in range(n):12       100      51063.0    510.6      0.1          result += math.sqrt(i) * math.sin(i)13                                               14         1  100114931.0    1e+08     99.9      time.sleep(0.1)15         1        367.0    367.0      0.0      return result

1.2 进阶使用

内存与运行时间综合分析

以下代码展示了一种整合内存与运行时间的性能分析示例,通过memory_profiler库监控内存消耗,借助LineProfiler分析代码执行时间。

from line_profiler import LineProfiler
# pip install memory_profiler
from memory_profiler import profile as memory_profileclass DataProcessor:# 监控该函数的内存运行情况@memory_profiledef process_large_dataset(self, data):return list(map(self.transform_item, data))def transform_item(self, item):return dict(x=item** 2, y=item * 3)processor = DataProcessor()
line_profiler = LineProfiler()
# 该函数被memory_profile装饰器包装,需要直接访问其原始未包装版本
line_profiler.add_function(processor.process_large_dataset.__wrapped__) 
line_profiler.add_function(processor.transform_item)test_data = list(range(100000))
line_profiler.enable()
result = processor.process_large_dataset(test_data)
line_profiler.disable()
line_profiler.print_stats()
Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================5     54.4 MiB     54.4 MiB           1       @memory_profile6                                             def process_large_dataset(self, data):7     85.1 MiB     30.7 MiB           1           return list(map(self.transform_item, data))Timer unit: 1e-07 sTotal time: 0.21659 s
File: /tmp/ipykernel_14853/4261432908.py
Function: process_large_dataset at line 5Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================5                                               @memory_profile6                                               def process_large_dataset(self, data):7         1    2165899.0 2.17e+06    100.0          return list(map(self.transform_item, data))Total time: 0.0929938 s
File: /tmp/ipykernel_14853/4261432908.py
Function: transform_item at line 9Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================9                                               def transform_item(self, item):10    100000     929938.0      9.3    100.0          return dict(x=item** 2, y=item * 3)

函数在多线程中的执行

line_profiler本身不区分线程,它会记录所有线程中被包装函数的执行情况。这意味着如果在多个线程中运行同一个被分析的函数,分析结果会将所有线程中该函数的执行数据汇总在一起。

from line_profiler import LineProfiler
import concurrent.futures
import time# 要分析的函数
def process_data(data):result = []# 模拟一些处理操作for i in range(data):result.append(i ** 2)time.sleep(0.001)  # 模拟耗时操作return sum(result)lprofiler = LineProfiler()
lp_wrapper = lprofiler(process_data)data_list = [100, 200, 150, 300, 250]# 使用线程池并行处理
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:# 提交任务时使用被包装的函数futures = [executor.submit(lp_wrapper, data) for data in data_list]results = [f.result() for f in futures]print("处理结果:", results)# 打印分析结果
print("\n=== 性能分析结果 ===")
lprofiler.print_stats()
处理结果: [328350, 2646700, 1113775, 8955050, 5177125]=== 性能分析结果 ===
Timer unit: 1e-09 sTotal time: 1.05548 s
File: /tmp/ipykernel_14853/3950115841.py
Function: process_data at line 6Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================6                                           def process_data(data):7         5       3495.0    699.0      0.0      result = []8                                               # 模拟一些处理操作9      1005     250388.0    249.1      0.0      for i in range(data):10      1000     686896.0    686.9      0.1          result.append(i ** 2)11      1000 1054522882.0    1e+06     99.9          time.sleep(0.001)  # 模拟耗时操作12         5      21281.0   4256.2      0.0      return sum(result)

适用范围

Line_profiler更适合分析执行时间远大于工具自身开销的代码,而不适用于过于简单的函数。当函数单次执行时间极短时,性能分析工具的追踪开销可能显著超过函数本身的运行时间,导致分析结果受到干扰,无法准确反映代码的真实性能。例如,对同一简单函数进行分析后,其执行时间反而比未分析时更长。反之,若整体执行时间足够长,性能分析工具的开销便可忽略不计,从而准确揭示代码的性能瓶颈。

from line_profiler import LineProfiler
import numpy as np  # 用numpy生成测试数据,放大工作量差异# 微小操作函数(未被性能分析)
def add_one(x):return x + 1  # 单次执行时间极短(纳秒级)
# 微小操作函数(将被性能分析)
def add_one_profile(x):return x + 1  # 单次执行时间极短(纳秒级)# 定义分析函数
def profile_add_one():# 循环调用,强制让微小操作累积执行for _ in range(1000000):add_one(1)add_one_profile(1)# 测试数据
lprofiler = LineProfiler()
lprofiler.add_function(add_one_profile)
lp_wrapper = lprofiler(profile_add_one)
lp_wrapper()
# 将时间单位设置为毫秒
# add_one_profile比add_one耗时
lprofiler.print_stats(output_unit=1e-3) 
Timer unit: 0.001 sTotal time: 0.114556 s
File: /tmp/ipykernel_14853/4261432908.py
Function: add_one_profile at line 8Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================8                                           def add_one_profile(x):9   1000000        114.6      0.0    100.0      return x + 1  # 单次执行时间极短(纳秒级)Total time: 1.14907 s
File: /tmp/ipykernel_14853/4261432908.py
Function: profile_add_one at line 12Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================12                                           def profile_add_one():13                                               # 循环调用多次add_one(强制让微小操作累积执行)14   1000001        148.9      0.0     13.0      for _ in range(1000000):15   1000000        286.9      0.0     25.0          add_one(1)16   1000000        713.3      0.0     62.1          add_one_profile(1)

2 参考

  • line_profiler-github
  • line_profiler-doc
  • Line by Line Profiling of Python Code
  • Line-by-line Analysis

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/945651.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

react的diff算法

这个算法用来比较虚拟dom和真实dom,从而最小化真实dom的更新 本质上是对两颗Fiber树的对比 (在Vue中是对旧VDOM树与新VDOM树的对比) 在不剪枝的情况下,时间复杂度接近O(n^3)基于最长公共子序列 (LCS) 的朴素计算为…

LLM学习记录DAY11

📘今日学习总结 tokenization分词算法 BPE分词(Byte-Pair Encoding)BPE 算法从一组基本符号(例如字母和边界字符)开始,迭代地寻找语料库中的两个相邻词元,并将它们替换为新的词元,这一过程被称为合并。 合并的…

ABP - 当前用户 [ICurrentUser、CurrentUser]

当前用户(Current User) 核心辅助类:ICurrentUser:获取当前登录用户信息(ID、用户名、角色等)。 CurrentUser:静态快捷访问(需在请求上下文内)。在ABP框架中,ICurrentUser和CurrentUser用于获取当前登录用户…

轮次检测模型 VoTurn-80M 开源,多模态融合架构;OpenAI 收购桌面助手 Sky:实时识别屏幕自然语言交互丨日报

开发者朋友们大家好:这里是 「RTE 开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的技术」、「有亮点的产品」、「有思考的文章」、「有态度…

ABP - 依赖注入和属性注入

一、依赖注入(Dependency Injection) 核心辅助类:IServiceCollection:扩展方法(如AddTransient、AddScoped)。 DependencyAttribute:标记注入生命周期(Transient/Scoped/Singleton)。 IIocResolver:手动解析…

ABP vNext 框架功能模块 - 依赖注入和属性注入

一、依赖注入(Dependency Injection) 核心辅助类:IServiceCollection:扩展方法(如AddTransient、AddScoped)。 DependencyAttribute:标记注入生命周期(Transient/Scoped/Singleton)。 IIocResolver:手动解析…

SAP维护汇率的关键Tcode

Tcode: OB08 维护汇率Tcode:OBBS 维护汇率的折算比率☆ No matter how much you change, you still have to pay the price for the things youve done.

幂函数

观察幂函数图像结论: 所有的幂函数都过1,1点,幂函数在第一象限必有图像。 a为负数时,不过0,0点,其余都有0,0点。 一、画函数用结论,a<0,单调递减,a>0,单调递增。 二、0<a<1之间,增的缓,a>1,…

ABP vNext 框架功能模块 - 动态API(Dynamic API)[RemoteServiceAttribute | DynamicApiControllerBuilder]

动态API(Dynamic API) 核心辅助类:DynamicApiControllerBuilder:动态生成API控制器。 RemoteServiceAttribute:标记类/方法为远程服务(自动暴露API)。在ABP框架中,DynamicApiControllerBuilder和RemoteService…

第4天(中等题 滑动窗口、哈希表)

打卡第四天 两道中等题哈希表记录元素频率:哈希表程序表示:滑动窗口+哈希表优化算法耗时≈一小时 明天继续 小tips:不小心删除可以用 Ctrl+Z 撤回刚刚消除的代码/文字

ABP vNext 框架功能模块 - 动态API(Dynamic API)

** 动态API(Dynamic API)** 核心辅助类:DynamicApiControllerBuilder:动态生成API控制器。 RemoteServiceAttribute:标记类/方法为远程服务(自动暴露API)。在ABP框架中,DynamicApiControllerBuilder和RemoteSe…

ABP vNext 框架功能模块 - 模块化(Modularity)

模块化(Modularity) 核心辅助类:AbpModule:所有模块的基类,定义模块生命周期方法。 DependsOnAttribute:声明模块依赖关系。 ModuleInitializer:模块初始化器(自动生成)。 IModuleContainer:模块容器,用于运…

ABP vNext 框架功能模块

以下是ABP框架中各核心功能的辅助类及示例说明,涵盖模块化、依赖注入、ORM集成等关键特性: 一. 模块化(Modularity) 核心辅助类:AbpModule:所有模块的基类,定义模块生命周期方法。 DependsOnAttribute:声明模块…

题解:P14299 [JOI2023 预选赛 R2] 填充 / Painting

\(\displaystyle \large {题目传送门}\) 题面 给定一个一个 H*W 的矩形 , 每个坐标上有一个颜色 , 上下左右相邻的同颜色节点可以形成连通块 。 你可以对任意一个连通块 , 进行一次并仅有一次的染色 , 求新形成的连…

Devolutions Server权限提升漏洞分析与修复指南

本文详细分析了CVE-2025-11957漏洞,该漏洞存在于Devolutions Server 2025.2.12.0及更早版本中,由于临时访问工作流程的授权机制存在缺陷,允许经过身份验证的基本用户通过精心构造的API请求自我批准或批准其他用户的…

AI股票预测分析报告 - 2025年10月24日 - 20:08:50

AI股票预测分析报告 - 2025年10月24日body { font-family: "Microsoft YaHei", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; color: rgba(51, 51, 51, 1); max-width: 1…

在 Astro 博客中优雅使用 51.la 统计数据

在 Astro 博客中使用 51.la 免费流量统计,通过解析 widget JS 自行渲染访问数据,既保留统计功能,又可自定义展示,让你直观了解博客访客情况作为老牌网站流量统计服务商,51.la 提供每月高达 1000 万次的免费统计额…

申威服务器安装Java11(swjdk-11u-9.ky10.sw_64.rpm)详细操作步骤(附安装包)

申威服务器安装Java11(swjdk-11u-9.ky10.sw_64.rpm)详细操作步骤(附安装包)​这是申威架构(国产芯片,常见于Kylin V10等国产系统)专用的 ​Java 11 版本(RPM安装包)​,包名为 java-11.0.7-swjdk-11u-9.ky10.…

str.endswith() 类似的方法

在Python中,与str.endswith()类似的方法(主要涉及字符串的开头/结尾检查、子串搜索等)有很多,以下是核心方法及其功能对比: 1. 开头检查:str.startswith()功能:检查字符串是否以指定前缀开头,返回True/False。…