百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

这些 Python 高效率技巧,一般人都不会

off999 2024-10-15 12:08 30 浏览 0 评论

作者:Martin Heinz

翻译:EarlGrey

原文:https://martinheinz.dev/blog/1

你估计已经看了不少关于 Python 技巧的文章,里面可能会提到变量拆包(unpacking)、局部函数等,但是 Python 还有很多不为人知的高效用法,等待着被人发现。本文将介绍作者纵观全网之后,都属于很少没提及的技巧。

清理字符串输入

清理用户输入的问题,几乎适用于我们可能编写的每个程序。通常将字符转换为小写或大写就足够了,这时只需要使用正则即可,但是对于复杂的情况,有一种更好的方法:

  1. user_input = "This\nstring has\tsome whitespaces...\r\n"


  2. character_map = {

  3. ord('\n') : ' ',

  4. ord('\t') : ' ',

  5. ord('\r') : None

  6. }

  7. user_input.translate(character_map) # This string has some whitespaces... "

在上述示例中,可以看到空格符“ \ n”和“ \ t”已被单个空格替换,而“ \ r”已被完全删除。这是一个简单的示例,但是我们可以更进一步,使用 unicodedata包及其combining函数生成范围更广的映射表,从字符串中删除所有重音符号。

迭代器切片

如果您尝试获取迭代器的切片,系统会报 TypeError,提示生成器对象不可下标,但是解决方案很简单:

  1. import itertools


  2. s = itertools.islice(range(50),10,20) # <itertools.islice object at 0x7f70fab88138>

  3. for val in s:

  4. ...

使用 itertools.islice,我们可以创建一个islice对象,该对象是产生所需元素的迭代器。不过,请务必注意,这会消耗所有生成器项,直到切片开始为止,而且还会消耗我们的“ islice”对象中的所有项。

Using itertools.islicewe can create aisliceobject which is an iterator that produces desired items. It's important to note though, that this consumes all generator items up until the start of slice and also all the items in ourisliceobject.

跳过可迭代对象的开始

有时候需要处理的文件里,明确存在一些不需要的数据行,但是我们不确定数量,比如说代码中的注释。这时, itertools再次为我们提供了简洁的方案:

  1. string_from_file = """

  2. // Author: ...

  3. // License: ...

  4. //

  5. // Date: ...


  6. Actual content...

  7. """


  8. import itertools


  9. for line in itertools.dropwhile(lambda line: line.startswith("//"), string_from_file.split("\n")):

  10. print(line)

这段代码仅在初始注释部分之后,才会产生数据行。如果我们只想在迭代器的开头丢弃数据,而又不知道有具体数量时,这个方法很有用。

仅带关键字参数(kwargs)的函数

有时候,使用仅支持关键字参数的函数可以让代码更加清晰易懂:

  1. def test(*, a, b):

  2. pass


  3. test("value for a", "value for b") # TypeError: test takes 0 positional arguments...

  4. test(a="value", b="value 2") # Works...

只需要在关键字参数前面再加一个 *参数,就可以轻松实现了。当然,如果还希望再加上位置参数,可以在*参数前面再增加。

创建支持 with语句的对象

我们都知道如何打开文件或使用 with语句获取锁,但是怎样自己可以实现类似的功能呢?一般来说,我们可以使用__enter____exit__方法来实现上下文管理器协议:

  1. classConnection:

  2. def __init__(self):

  3. ...


  4. def __enter__(self):

  5. # Initialize connection...


  6. def __exit__(self, type, value, traceback):

  7. # Close connection...


  8. withConnection as c:

  9. # __enter__ executes

  10. ...

  11. # conn.__exit__ executes

上面是最常见的实现方式,但是还有一种更简单的方法:

  1. from contextlib import contextmanager


  2. @contextmanager

  3. def tag(name):

  4. print(f"<{name}>")

  5. yield

  6. print(f"")


  7. with tag("h1"):

  8. print("This is Title.")

上面的代码段使用 contextmanager管理器装饰器实现了内容管理协议。进入“ with”块时,执行“ tag”函数的第一部分(在“ yield”之前),然后执行yield,最后执行其余部分。

用 __slots__节省内存

如果程序需要创建大量的类实例,我们会发现程序占用了大量内存。这是因为 Python 使用字典来表示类实例的属性,这样的话创建速度很快,但是很耗内存。如果内存是你需要考虑的一个问题,那么可以考虑使用 __slots__

  1. classPerson:

  2. __slots__ = ["first_name", "last_name", "phone"]

  3. def __init__(self, first_name, last_name, phone):

  4. self.first_name = first_name

  5. self.last_name = last_name

  6. self.phone = phone

当我们定义 __slots__属性时,Python会使用固定大小的数组(占用内存少)来存储属性,而不是字典,这大大减少了每个实例所需的内存。不过使用__slots__还有一些缺点:无法声明任何新属性,我们只能使用__slots__中的那些属性。同样,带有__slots__的类不能使用多重继承。

限制CPU和内存使用量

如果不是想优化程序内存或CPU使用率,而是想直接将其限制为某个数值,那么Python也有一个可以满足要求的库:

  1. import signal

  2. import resource

  3. import os


  4. # To Limit CPU time

  5. def time_exceeded(signo, frame):

  6. print("CPU exceeded...")

  7. raiseSystemExit(1)


  8. def set_max_runtime(seconds):

  9. # Install the signal handler and set a resource limit

  10. soft, hard = resource.getrlimit(resource.RLIMIT_CPU)

  11. resource.setrlimit(resource.RLIMIT_CPU, (seconds, hard))

  12. signal.signal(signal.SIGXCPU, time_exceeded)


  13. # To limit memory usage

  14. def set_max_memory(size):

  15. soft, hard = resource.getrlimit(resource.RLIMIT_AS)

  16. resource.setrlimit(resource.RLIMIT_AS, (size, hard))

在这里,我们可以设置了最大cpu运行时间以及最大内存使用限制的两个选项。对于cpu限制,我们首先获得该特定资源( RLIMIT_CPU)的软限制和硬限制,然后使用参数指定的秒数和先前获取的硬限制来设置。

最后,我们注册了一个在超过CPU时间后,让系统退出的信号。至于内存,我们再次获取软限制和硬限制,并使用带有大小参数的 setrlimit和硬限制完成配置

控制导入的内容

某些语言提供了导出成员(变量,方法,接口)的显式机制,例如Golang,它仅导出以大写字母开头的成员。但是在Python中,所有对象都会导出,除非我们使用 __all__

  1. def foo:

  2. pass


  3. def bar:

  4. pass


  5. __all__ = ["bar"]

上面的代码段中,只会导出 bar函数。另外,如果__all__的值为空,那么不会导出任何函数,而且在导入该模块时系统会报AttributeError

实现比较运算符

如果我们要逐一为某个类实现所有的比较运算符,你肯定会觉得很麻烦,因为要实现的方法还不少,有 __lt__,__le__,__gt__,__ge__

其实,Python 提供了一种便捷的实现方式,就是通过 functools.total_ordering装饰器。

  1. from functools import total_ordering


  2. @total_ordering

  3. classNumber:

  4. def __init__(self, value):

  5. self.value = value


  6. def __lt__(self, other):

  7. returnself.value < other.value


  8. def __eq__(self, other):

  9. returnself.value == other.value


  10. print(Number(20) >Number(3))

  11. print(Number(1) <Number(5))

  12. print(Number(15) >=Number(15))

  13. print(Number(10) <=Number(2))

这是怎么实现的呢? total_ordering可以用来简化实现类排序的过程。我们只需要定义__lt____eq__(这是映射剩余操作的最低要求),然后就交给装饰器去完成剩余的工作了。

结语

在日常Python编程时,上述特性并非都是必不可少的和有用的,但是其中某些功能可能会不时派上用场,并能简化冗长且令人讨厌的任务。

还要指出的是,所有这些功能都是Python标准库的一部分,而在我看来,其中一些功能似乎不像是应该在标准库中的功能。

因此,每当你决定要用Python实现某些功能时,都请先在标准库中找一找,如果找不到合适的库,那么可能是因为查找的姿势不对。而且即使标准库里没有,有很大的概率已经存在一个第三方库了!

签到送书计划

自律改变自我!第①期打卡送书活动启动!

相关推荐

阿里云国际站ECS:阿里云ECS如何提高网站的访问速度?

TG:@yunlaoda360引言:速度即体验,速度即业务在当今数字化的世界中,网站的访问速度已成为决定用户体验、用户留存乃至业务转化率的关键因素。页面加载每延迟一秒,都可能导致用户流失和收入损失。对...

高流量大并发Linux TCP性能调优_linux 高并发网络编程

其实主要是手里面的跑openvpn服务器。因为并没有明文禁p2p(哎……想想那么多流量好像不跑点p2p也跑不完),所以造成有的时候如果有比较多人跑BT的话,会造成VPN速度急剧下降。本文所面对的情况为...

性能测试100集(12)性能指标资源使用率

在性能测试中,资源使用率是评估系统硬件效率的关键指标,主要包括以下四类:#性能测试##性能压测策略##软件测试#1.CPU使用率定义:CPU处理任务的时间占比,计算公式为1-空闲时间/总...

Linux 服务器常见的性能调优_linux高性能服务端编程

一、Linux服务器性能调优第一步——先搞懂“看什么”很多人刚接触Linux性能调优时,总想着直接改配置,其实第一步该是“看清楚问题”。就像医生看病要先听诊,调优前得先知道服务器“哪里...

Nginx性能优化实战:手把手教你提升10倍性能!

关注△mikechen△,十余年BAT架构经验倾囊相授!Nginx是大型架构而核心,下面我重点详解Nginx性能@mikechen文章来源:mikechen.cc1.worker_processe...

高并发场景下,Spring Cloud Gateway如何抗住百万QPS?

关注△mikechen△,十余年BAT架构经验倾囊相授!大家好,我是mikechen。高并发场景下网关作为流量的入口非常重要,下面我重点详解SpringCloudGateway如何抗住百万性能@m...

Kubernetes 高并发处理实战(可落地案例 + 源码)

目标场景:对外提供HTTPAPI的微服务在短时间内收到大量请求(例如每秒数千至数万RPS),要求系统可弹性扩容、限流降级、缓存减压、稳定运行并能自动恢复。总体思路(多层防护):边缘层:云LB...

高并发场景下,Nginx如何扛住千万级请求?

Nginx是大型架构的必备中间件,下面我重点详解Nginx如何实现高并发@mikechen文章来源:mikechen.cc事件驱动模型Nginx采用事件驱动模型,这是Nginx高并发性能的基石。传统...

Spring Boot+Vue全栈开发实战,中文版高清PDF资源

SpringBoot+Vue全栈开发实战,中文高清PDF资源,需要的可以私我:)SpringBoot致力于简化开发配置并为企业级开发提供一系列非业务性功能,而Vue则采用数据驱动视图的方式将程序...

Docker-基础操作_docker基础实战教程二

一、镜像1、从仓库获取镜像搜索镜像:dockersearchimage_name搜索结果过滤:是否官方:dockersearch--filter="is-offical=true...

你有空吗?跟我一起搭个服务器好不好?

来人人都是产品经理【起点学院】,BAT实战派产品总监手把手系统带你学产品、学运营。昨天闲的没事的时候,随手翻了翻写过的文章,发现一个很严重的问题。就是大多数时间我都在滔滔不绝的讲理论,却很少有涉及动手...

部署你自己的 SaaS_saas如何部署

部署你自己的VPNOpenVPN——功能齐全的开源VPN解决方案。(DigitalOcean教程)dockovpn.io—无状态OpenVPNdockerized服务器,不需要持久存储。...

Docker Compose_dockercompose安装

DockerCompose概述DockerCompose是一个用来定义和管理多容器应用的工具,通过一个docker-compose.yml文件,用YAML格式描述服务、网络、卷等内容,...

京东T7架构师推出的电子版SpringBoot,从构建小系统到架构大系统

前言:Java的各种开发框架发展了很多年,影响了一代又一代的程序员,现在无论是程序员,还是架构师,使用这些开发框架都面临着两方面的挑战。一方面是要快速开发出系统,这就要求使用的开发框架尽量简单,无论...

Kubernetes (k8s) 入门学习指南_k8s kubeproxy

Kubernetes(k8s)入门学习指南一、什么是Kubernetes?为什么需要它?Kubernetes(k8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序。它...

取消回复欢迎 发表评论: