Python进阶:9个提升代码质量与性能的实用技巧
本文深入解析Python标准库中的9个高级技巧,涵盖字符串处理、迭代器切片、关键字参数限制、上下文管理器实现、内存节省策略及资源限制等。通过实际代码示例,展示如何利用内置模块提升代码效率与规范性,帮助开发者写出更优雅、高性能的Python程序。
本文将深入探讨Python高手常用的高效技巧,带你一探究竟。欢迎收藏学习,点赞支持,欢迎交流。
整理字符串输入
在编程过程中,处理用户输入的字符串整理问题十分常见。下面介绍一种更优的解决方案:
user_input = "This
string has some whitespaces...
"
character_map = {
ord(
) : ,
ord( ) : ,
ord(
) : None
}
user_input.translate(character_map) # This string has some whitespaces...
在此示例中,可以看到空格符「n」和「t」均被替换为相应数量的空格,而「r」则被移除。这只是一个简单的示例,我们可以进一步使用「unicodedata」模块生成大型重映射表,并利用其中的「combining()」函数进行生成和映射操作。
迭代器(切片)
如果直接对返回对象进行简单操作,可能会触发生成对象下的“TypeError”,但我们可以采用以下方案解决问题:
import itertools
s = itertools.islice(range(50), 10, 20) # <itertools.islice object at 0x7f70fab88138>
for val in s:
...
我们可以使用「itertools.islice」创建一个「islice」对象,该对象是一个迭代器,能够产生我们所需的项。需要注意的是,该操作需作用于对象及其所有生成器项,即「islice」对象中的所有项。
跳过可迭代对象的开头
有时我们需要处理文件开头不需要的行(如注释)。「itertools」再次提供了一种简洁的解决方案:
string_from_file = """
// Author: ...
// License: ...
//
// Date: ...
Actual content...
"""
import itertools
for line in itertools.dropwhile(lambda line: line.startswith("//"), string_from_file.split("
")):
print(line)
这段代码仅打印初始注释部分之后的内容。如果我们只想舍弃可迭代对象的开头部分(本示例中为开头的注释行),且不知道这部分具体长度时,这种方法便显得尤为实用。
只包含关键字参数的函数 (kwargs)
当我们使用以下函数定义时,创建仅接受关键字参数作为输入的函数,有助于提供更清晰的函数定义:
def test(*, a, b):
pass
test("value for a", "value for b") # TypeError: test() takes 0 positional arguments...
test(a="value", b="value 2") # Works...
如你所见,在关键字参数之前加上一个「*」即可解决此问题。如果我们将某些参数放在「*」参数之前,它们显然被视为位置参数。
创建支持「with」语句的对象
举例而言,我们都熟知如何使用「with」语句打开文件或获取锁,但我们能否实现自定义的上下文表达式呢?答案是肯定的,我们可以使用「__enter__」和「__exit__」来实现上下文管理协议:
class Connection:
def __init__(self):
...
def __enter__(self):
# Initialize connection...
def __exit__(self, type, value, traceback):
# Close connection...
with Connection() as c:
# __enter__() executes
...
# conn.__exit__() executes
这是在 Python 中最常见的实现上下文管理的方法,但还有更简便的方式:
from contextlib import contextmanager
@contextmanager
def tag(name):
print(f"<{name}>")
yield
print(f"</{name}>")
with tag("h1"):
print("This is Title.")
上述代码使用「contextmanager」装饰器实现了上下文管理协议。当进入「with」块时,「tag」函数的第一部分(即「yield」之前的部分)会先执行,随后执行「with」块内的代码,最后再执行「tag」函数的剩余部分。
用「__slots__」节省内存
如果你曾经编写过创建某种类的大量实例的程序,可能会注意到程序突然需要大量内存。这是因为 Python 使用字典来表示类实例的属性,虽然速度较快,但内存使用效率并不高。通常情况下,这并非严重问题。但如果你的程序因此受到严重影响,不妨尝试使用「__slots__」:
class Person:
__slots__ = ["first_name", "last_name", "phone"]
def __init__(self, first_name, last_name, phone):
self.first_name = first_name
self.last_name = last_name
self.phone = phone
当我们定义了「__slots__」属性时,Python 不再使用字典来表示属性,而是使用小型固定大小的数组,这大大减少了每个实例所需的内存。使用「__slots__」也存在一些缺点:我们不能声明任何新属性,只能使用「__slots__」中已定义的属性。此外,带有「__slots__」的类无法使用多重继承。
限制「CPU」和内存使用量
如果不是为了优化程序对内存或 CPU 的使用率,而是想直接将资源限制为某个确定的数值,Python 也有相应的库可以实现这一目标:
import signal
import resource
import os
# To Limit CPU time
def time_exceeded(signo, frame):
print("CPU exceeded...")
raise SystemExit(1)
def set_max_runtime(seconds):
# Install the signal handler and set a resource limit
soft, hard = resource.getrlimit(resource.RLIMIT_CPU)
resource.setrlimit(resource.RLIMIT_CPU, (seconds, hard))
signal.signal(signal.SIGXCPU, time_exceeded)
# To limit memory usage
def set_max_memory(size):
soft, hard = resource.getrlimit(resource.RLIMIT_AS)
resource.setrlimit(resource.RLIMIT_AS, (size, hard))
我们可以看到,在上面的代码片段中,同时包含了设置最大 CPU 运行时间和最大内存使用限制的选项。在限制 CPU 运行时间时,我们首先获取该特定资源(RLIMIT_CPU)的软限制和硬限制,然后使用通过参数指定的秒数和先前检索到的硬限制进行设置。最后,如果 CPU 运行时间超过限制,我们将发出系统退出信号。在内存使用方面,我们再次检索软限制和硬限制,并使用带有「size」参数的「setrlimit」和先前检索到的硬限制进行设置。
控制可以/不可以导入什么
有些语言有非常明显的机制来导出成员(变量、方法、接口),例如在 Golang 中只有以大写字母开头的成员被导出。然而,在 Python 中,所有成员都会被导出(除非我们使用了「__all__」):
def foo():
pass
def bar():
pass
__all__ = ["bar"]
在上述代码中,我们知道只有「bar」函数被导出了。同样,我们可以让「__all__」为空,这样就不会导出任何东西,当从这个模块导入时,会引发「AttributeError」。
实现比较运算符的简便方法
为一个类实现所有比较相似方法(如 lt, le, gt, ge)是非常繁琐的。有更简便的方法吗?此时,「functools.total_ordering」就是一个很好的帮手:
from functools import total_ordering
@total_ordering
class Number:
def __init__(self, value):
self.value = value
def __lt__(self, other):
return self.value < other.value
def __eq__(self, other):
return self.value == other.value
print(Number(20) > Number(3))
print(Number(1) < Number(5))
print(Number(15) >= Number(15))
print(Number(10) <= Number(2))
这里的工作原理究竟是怎样的呢?我们使用「total_ordering」装饰器简化了对类实例排序的过程。我们只需要定义「__lt__」和「__eq__」即可,它们是实现其余操作所需的最小集合(这也体现了装饰器的作用——为我们填补空白)。
结语
并非本文中所有相关的功能在日常使用的 Python 编程中都是特定或常用的,但某些功能可能在特定场景下派上用场,而且它们也可能让一些原本冗长且令人厌烦的任务变得简单。还需指出的是,所有这些功能都是 Python 标准库的一部分。使用功能时,请先查看 Python 标准库,如果你没有找到想要的功能,可能只是因为你还没有努力寻找(如果真的没有,那肯定也存在于一些可用库中)。
技术交流
欢迎转载、收藏,有所收获请点赞支持!

到此这篇关于分享介绍Python的9个实用技巧的文章就介绍到这了,更多相关Python 技巧内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













