Python 高阶升级技巧


废话不多说,下面介绍几个python高阶技巧,突破思维限制。

技巧 1:利用迭代器和生成器的力量

如果你对 Python 的核心原理了如指掌,那么你很可能对迭代器和生成器的基础知识了如指掌。生成器是Python中的一个重要特性,它可以使用yield语句来生成一个可迭代对象,我们进一步深入探讨它们的功能。想象一下:你需要筛选一个长达数百万行的大型日志文件。试图将整个文件加载到内存中将会带来灾难性的后果。这时,生成器就能派上大用了!

代码示例

常用方法

def process_huge_file(filename):
    all_lines = open(filename).readlines()  # Yikes!一次加载所有内容
    results = []
    for line in all_lines:
        # 对每一行进行处理
        results.append(process_line(line)) 
    return results

高阶技巧

def process_huge_file_generator(filename):
    with open(filename) as f:
        for line in f:
            yield process_line(line)  # 按需处理,无巨型列表

# 使用生成器
for result in process_huge_file_generator("massive_log.txt"):
    # 对每个结果进行处理

注意到了不同之处?

生成器方法逐一处理文件,并根据需要生成结果。即使面临大量数据集,也能保持正常的内存使用率。这是众多大厂处理大规模数据的核心原则--规模效率。

想要更加复杂吗?

将生成器连锁起来,构建出优雅的数据处理管道!

生成器连锁是一种非常强大的数据处理技术,它可以帮助我们构建出高效、优雅的数据处理管道。通过将生成器连锁在一起,我们可以构建出复杂的数据处理流程,而不需要一次性将全部数据加载到内存中。

要构建优雅的数据处理管道,你可以使用生成器和管道操作符(如|)来连锁起来。生成器是一种特殊的迭代器,可以逐步生成数据,而管道操作符可以将生成器连接起来,将一个生成器的输出作为下一个生成器的输入。

# 创建一个生成器,生成一系列数字
def number_generator(n):
    for i in range(1, n + 1):
        yield i

# 创建一个生成器,对接收的数字进行平方
def square_generator(nums):
    for num in nums:
        yield num * num

# 创建一个生成器,对接收的数字进行累加
def sum_generator(nums):
    total = 0
    for num in nums:
        total += num
        yield total

# 使用管道操作符连接生成器,构建数据处理管道
result = number_generator(5) | square_generator | sum_generator

# 遍历处理结果
for value in result:
    print(value)

在这个例子中,我们首先创建了三个生成器number_generatorsquare_generatorsum_generator,分别用来生成数字、对数字进行平方和对数字进行累加。然后使用管道操作符将它们连接起来,构建出一个数据处理管道。最后遍历处理结果,可以看到数据依次经过三个生成器的处理。

通过这种方式,你可以构建出优雅的数据处理管道,利用生成器和管道操作符来实现数据处理流程的组合和重用。

这里还有个读取文件的例子。没有直接使用管道符"|"

# 定义第一个生成器,用于读取文件中的数据
def read_file(filename):
    with open(filename, 'r'as file:
        for line in file:
            yield line

# 定义第二个生成器,用于对文本进行处理
def process_text(lines):
    for line in lines:
        # 在这里可以进行各种文本处理操作,比如分词、去除停用词等
        # 这里简单示范将每行转换为大写
        yield line.upper()

# 定义第三个生成器,用于输出处理后的数据
def write_to_file(lines, output_filename):
    with open(output_filename, 'w'as file:
        for line in lines:
            file.write(line)

# 将生成器连锁起来构建数据处理管道
input_file = 'input.txt'
output_file = 'output.txt'

data = read_file(input_file)
processed_data = process_text(data)
write_to_file(processed_data, output_file)

在这个示例中,read_file函数从文件中逐行读取数据并返回生成器,process_text函数对每行文本进行处理并返回生成器,write_to_file函数将处理后的数据写入到文件中。通过将这些生成器连锁在一起,我们构建了一个优雅的数据处理管道,使得我们可以高效地处理大规模的数据而不需要一次性将全部数据加载到内存中。

更多优质内容,请关注@公众号:数据STUDIO

技巧 2:利用装饰器提升技能

如果你曾经对装饰器感到头昏脑涨,那就大错特错了。起初它们可能看起来像魔法一般,但实际上它们只是你能够添加到函数上的一些花哨附加组件。需要计算函数的运行时间?有一个装饰器能够解决这个问题。想要添加日志记录?再来一个装饰器!这就好比让函数获得了超能力一样。

关键在于装饰器可以帮助你摆脱编写重复模板代码的困扰。需要对多个函数执行相同的设置步骤?一个巧妙设计的装饰器就能够解决这个问题。就像给编码过程添上了一件时髦新衣一样,迅速变得更有趣了。

装饰器示例

def my_timer(func):
    import time
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took: {end-start:.4f} seconds")
        return result
    return wrapper

@my_timer  # Look, no messy setup!
def slow_function(n):
    time.sleep(n)

装饰器虽好,但不要过度使用

装饰符非常棒,但就像你不会穿着燕尾服去杂货店一样,要明智地使用它们。过多的装饰会让你的代码更难理解。

技巧 3:发挥多进程的作用

您的电脑在执行哪些任务时运转不畅呢?如果您一直在等待计算完成或处理大量文件,那么利用多进程处理将大大提升速度。原理是这样的:大多数现代电脑都拥有多个 CPU 内核,但往往没有得到充分利用。多核处理器能充分发挥它们的作用!

使用多核处理器的时机:CPU密集型任务

  • CPU密集型任务包括严格的数值计算、图像处理和复杂的模拟。如果电脑的 CPU 是限制因素,那么多核处理器可能是一个解决方案。
  • 独立任务:你的问题是否能够分解成可以同时处理的小块?这时非常适合使用多处理。

代码示例:并行

假设你需要调整一大批图片的大小。每张图片都可以独立处理,这就是典型的多处理方案:

import multiprocessing

def resize_image(image_path):
    # (Your image resizing code here)
    ...

if __name__ == "__main__":
    image_paths = [...]  # Load your list of image files
    with multiprocessing.Pool() as pool:  # Create a worker pool
        pool.map(resize_image, image_paths)  # Magic happens here!

为何这么重要

pool.map函数可以神奇地将图像大小调整工作分配给所有可用的CPU内核。以往需要花费很长时间的工作,现在只需很短的时间就能完成。

多处理是Python出色扩展的一种方式。但请记住,它并非适用于所有情况。比如网络绑定任务(等待网站响应)就无法获得同样的好处。了解何时使用多处理(何时不使用)才是真正的力量源泉。

技巧 4:重视代码测试

在高质量的软件开发过程中,代码测试是一个关键且不可或缺的环节。未经严格测试的代码就如一枚定时炸弹,随时可能导致项目功能异常和声誉受损。因此,从一开始就应当培养良好的测试习惯,而不是等到问题发生后不得不事后补救。

测试的重要性:

  • 尽早发现缺陷:问题被及时发现,修复的成本就越低。
  • 自信编写代码:测试为代码修改和重构提供了安全保障,无需过度担忧。
  • 睡眠质量改善:确保系统按预期运行,可以减轻开发者的精神压力。

测试失败导致的教训

我之所以如此重视测试,是由于曾经的一次深刻教训。之前有一次,一个同事为了快速开发新功能而忽视了测试环节,结果一个看似微小的改动引发了连锁反应,导致系统的其他无关部分发生严重崩溃。那次事故让同事焦头烂额地修复了一个下午,从那以后,我就成为了测试的坚定拥护者。

使用 Python 的 unittest 的简单示例

import unittest

def calculate_average(numbers):
    if len(numbers) == 0:
        return 0  # Return 0 for empty lists to avoid division by zero
    return sum(numbers) / len(numbers)

class TestAverage(unittest.TestCase):
    def test_empty_list(self):
        result = calculate_average([])
        self.assertEqual(result, 0)

    def test_basic_average(self):
        result = calculate_average([246])
        self.assertEqual(result, 4)

if __name__ == '__main__':
    unittest.main()

从小处做起,覆盖代码的关键部分,并不断扩展测试。这是一项会带来十倍回报的投资。

技巧 5:采用异步方式,提升速度

生活并非总是按部就班、有条不紊地进行。有时,你会发现自己需要等待网页加载、文件下载完成或数据库查询结束。这就是异步编程概念的用武之地,它允许你同时管理多个活动。跟更多内容可阅读👉Python 最强异步编程:Asyncio

为何选择异步编程?

  • 避免阻塞:传统代码经常会造成阻塞--在等待缓慢的事物时,程序会处于空闲状态。异步编程可以让程序在此期间执行其他任务。
  • 响应式应用程序:想象一下构建一个网络应用程序。如果一个请求需要很长时间,异步技术可以防止应用程序冻结。
  • 处理 I/O 绑定问题:网络请求、文件操作......都是异步处理的首选。

使用 asyncio 的简单示例

import asyncio
import aiohttp  # Library for async web requests

async def fetch_data(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    tasks = [fetch_data("https://api.example.com/data1"),
             fetch_data("https://api.example.com/data2")]
    results = await asyncio.gather(*tasks)
    # Process both results 

if __name__ == "__main__":
    asyncio.run(main())

工作原理

  • asyncio 是 Python 的内置 async 库。
  • async def 标记函数为协程(一种特殊的可暂停和恢复函数)。
  • await 的神奇之处在于,它指示 Python 暂停执行并等待某些事件(如网络请求)完成。
  • asyncio.gather 允许同时运行多个程序。

这个工作原理看起来很不错!asyncio 的确是一个强大的库,它使得编写异步代码变得更加简单和高效。同时,async defawait 的结合也让编写异步函数更加直观和易懂。而asyncio.gather更是提供了方便的方式来同时运行多个异步任务。这些工具的结合确实为编写异步代码提供了很多便利。有需要的话,我可以为你提供更多关于asyncio和异步编程的信息。


🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉 PythonMySQL数据分析数据可视化机器学习与数据挖掘爬虫 等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递

相关推荐

  • 如何快速理清复杂Python代码?
  • 语音克隆达到人类水平,微软全新VALL-E 2模型让DeepFake堪比配音员
  • 无表情人脸预测政治信仰,AI准确率惊人!斯坦福研究登国际顶刊
  • OpenAI正在「吞噬」媒体
  • 贾扬清十年经典之作获时间检验奖!ICML 2024十篇最佳论文开奖,爆火SD3、谷歌Genie在列
  • Llama 3.1横空出世!开源巨无霸首次击溃闭源,全民GPT-4时代来临
  • Java之父官宣退休前推荐,这本书每个开发者必读!
  • 大模型Infra这些年,从黑铁时代到黄金时代再到白银时代
  • 9 月生效!微软:全部中国员工禁止使用华为、小米安卓设备办公!网友解读:原因真不是系统歧视!
  • 最强开源模型 Llama-3.1 正式发布!马斯克搞了10万块H100
  • 【全网最全教程】实现大文件上传以及断点续传
  • 提升20%!京东广告模型系统负载均衡揭秘
  • 一天干了多少活儿,摸了多少鱼,这个工具一目了然给你统计出来
  • 解密列表的创建与销毁,以及缓存池长什么样子?
  • 答应我,不要再用console.log调试了
  • 前端程序员,到底要怎么去性能优化?
  • 百分百有奖 | EdgeOne安全能力开箱测评挑战赛
  • 中台的故事与事故
  • Vue3 泛型组件:灵活而强大!!!
  • 网页从10s优化到0.5s