一、前言
每种流行的通用编程语言都有一个功能丰富、组织良好的标准库,可以帮助开发者使用预先开发的函数或类来提高编码效率。一些编程语言提供预导入的对象或函数来访问标准库,例如JavaScript。而有些语言则提供单独的可导入模块。Python的标准库中有许多有用的预开发的可导入模块,提供各种自解释的类和函数。
每个Python开发者通常都了解一些流行的通用标准库模块,如re、datetime、math、random等。这些只是Python标准库提供的众多模块中的一小部分。Python提供了许多内置的标准模块,可以提高编码效率,并减少外部依赖。
在这篇文章中,将列举一些鲜为人知但很有帮助的内置Python标准库模块,可以使用它们来提高编码效率!
二、使用ipaddress模块处理IP地址数据
开发者经常使用Python创建DevOps自动化脚本和计算机网络相关程序,因此存储和操作IP地址数据成为Python中的一般需求。内置的ipaddress模块为IPv4和IPv6提供了预开发的类,用于存储和操作IP地址和网络配置。
例如,你可以从字符串或整数创建一个IPv4地址对象,如下所示。
import ipaddress
addr_1 = ipaddress.ip_address('192.150.1.2')
addr_2 = ipaddress.ip_address(202)
print(addr_1) # 192.150.1.2
print(addr_2) # 0.0.0.202
print(type(addr_1)) #
我们可以使用传统的算术运算符与IP地址对象进行比较和数据操作。例如,你可以增加/减少和比较IP地址对象,如以下代码片段所示。
import ipaddress
addr = ipaddress.ip_address('192.150.1.2')
print(addr + 2) # 192.150.1.4
print(addr - 10) # 192.150.0.248
print(addr - 2 == ipaddress.ip_address('192.150.1.0') ) # True
print(addr <= ipaddress.ip_address('192.150.1.0') ) # False
该模块还允许你使用CIDR表示法来处理计算机网络,并提供网络配置。例如,以下代码片段将打印192.150.100.0/24网络配置中的所有可用主机IP。
import ipaddress
net = ipaddress.ip_network('192.150.100.0/24')
print(type(net)) #
for h in net.hosts():
print(h)
三、使用cmd模块创建交互式shell
有两种类型的命令行界面(CLI)程序:基于进程的程序和交互式shell。基于进程的CLI程序通常提供各种命令和选项来执行进程,这些进程在执行后会终止CLI程序。与此同时,交互式CLI程序通过运行一个永无止境的命令执行循环来接受命令。官方的Python REPL是一个很好的交互式shell示例。
内置的cmd模块提供了一个预先开发的类,用于在Python中创建交互式shell。你可以用自己的Python类扩展cmd.Cmd类,并按如下方式执行命令。
import cmd
class Calc(cmd.Cmd):
prompt = 'calc > '
intro = 'Welcome to Calc. Use add, sub, and help commands'
def do_add(self, args):
'Adds two integers and returns the result'
a, b = map(int, args.split())
print(a + b)
def do_sub(self, args):
'Subtracts two integers and returns the result'
a, b = map(int, args.split())
print(a - b)
if __name__ == '__main__':
Calc().cmdloop()
上述交互式CLI程序实现了add和sub命令,每个命令接受两个参数。例如,你可以输入add 10 5来执行10和5的算术加法运算。这个命令行shell创建类非常灵活,而且可以自定义——它允许你自定义提示符和欢迎信息,如上面的代码片段所示。
该模块还能自动创建帮助命令,打印每条命令的相关信息,通过运行可用命令来尝试使用上面的代码。
使用cmd模块创建的交互式shell示例
你可以通过创建一个带有do_前缀的函数来添加新命令,并为帮助命令使用doc注释。cmd模块并不能以开发者友好的方式解析命令行选项,但毫无疑问,你可以将argparse模块与cmd集成,以实现可用命令的选项。
四、使用decimal和fractions模块进行算术处理
通常,每种流行的编程语言都提供了内置的浮点类型来表示浮点数。但是,这些内置的浮点数在内部使用C语言的硬件级double或float数据类型,该类型使用IEEE-754标准浮点表示法。这种标准会导致某些十进制数四舍五入的问题。
print(0.1 + 0.2 == 0.3) # False
print(0.1 + 0.2) # 0.30000000000000004
内置的decimal模块提供了另一种基于软件的实现方式,可以处理小数,而不会出现四舍五入的问题,从而使小数计算更加精确。
from decimal import Decimal
print(Decimal('0.1') + Decimal('0.2')) # 0.3
从上面的示例中可以看出,你可以对十进制对象使用传统的算术运算符。
内置的fractions模块可以帮助我们存储和计算有理数。该模块提供的Fraction类具有以下构造函数,可以轻松创建有理数。
class fractions.Fraction(numerator=0, denominator=1)
class fractions.Fraction(other_fraction)
class fractions.Fraction(float)
class fractions.Fraction(decimal)
class fractions.Fraction(string)
如以下代码片段所示,Fraction类也可以使用与Decimal类类似的算术运算符。
from fractions import Fraction
print(Fraction('1/2') + Fraction('1/6')) # 2/3
print(Fraction(1, 8) * 2) # 1/4
print(Fraction(0.1) / Fraction(0.2)) # 1/2
fractions模块利用math标准模块中的一些函数,基于Python实现。
分数加法的源代码
五、使用Enum模块创建枚举
大多数编程语言都提供内置的枚举类型,用于创建一组可以轻松赋值给其他标识符的常量。例如,你可以使用枚举对象表示工作日或预定义的颜色集。过去,Python没有提供创建枚举的内置方式,因此开发者不得不使用常量、字典和自定义枚举类等替代方法。
Python在3.4版本中引入了标准的enum模块,提供了一个功能完备的解决方案来创建枚举值。
enum模块支持基于类和函数的方式初始化枚举集。
from enum import Enum
class AppMode(Enum):
DEBUG = 1
PRODUCTION = 2
TEST = 3
mode = AppMode.DEBUG
print(mode == AppMode.DEBUG) # True
Priority = Enum('Priority', ['LOW', 'MEDIUM', 'CRITICAL'])
print([e.name for e in Priority]) # ['LOW', 'MEDIUM', 'CRITICAL']
你甚至可以使用这个模块的Flag类创建支持位运算的标志。这个功能在开发Python库时非常有帮助,可以创建支持位运算的选项。
请看下面的例子,它使用位运算在单个标识符上存储了多个标志值。
from enum import Flag, auto
class LauncherConfig(Flag):
CENTERED_WINDOW = auto()
SHOW_FRAME = auto()
DARK_THEME = auto()
config = LauncherConfig.SHOW_FRAME | LauncherConfig.DARK_THEME
print(config) # LauncherConfig.DARK_THEME|SHOW_FRAME
print(LauncherConfig.DARK_THEME in config) # True
六、使用inspect模块进行生产力式元编程
元编程指的是一种将程序结构本身作为数据处理的编程概念。元编程概念通过减少特定开发需求所需的代码行数来帮助提高编码效率。例如,你可以通过检查对象的方法来调用对象的所有可用方法,而不必手工静态编写每个类的方法。
Python提供了一些内置函数用于基本的元编程。它还提供了功能丰富的inspect模块用于高级元编程需求。
请看下面的代码片段,它调用了一个简单对象的所有方法。
import inspect
class A:
def a(self):
print('a')
def b(self):
print('b')
def c(self):
print('c')
a = A()
for _, m in inspect.getmembers(a, predicate=inspect.ismethod):
m() # a b c
这个模块提供了一种高效的方式来检查可调用函数。请看下面的示例代码片段,它将在控制台上打印函数参数。
import inspect
def display(name: str, score: int = 50):
print('Hello %s, your score is %d.' % (name, score))
sig = inspect.signature(display)
for p in sig.parameters.values():
print(p)
signature()函数使用有序字典数据结构返回给定可调用函数的所有参数。它提取参数名称、类型提示和默认值,如下图所示。
使用inspect模块检查函数参数
PythonFire开源项目利用inspect模块将Python源代码转换为功能齐全的命令行程序,可以尝试使用inspect模块构建一些超棒的程序。
七、使用textwrap和colorsys便利模块
有时,编程语言提供预先开发的函数或类来实现流行的通用算法,以提高开发者的工作效率。Python提供了包含文本包装算法的textwrap模块和包含颜色系统转换算法的colorsys模块。
textwrap模块提供了预先开发的函数,用于对文本数据进行包装、缩短、缩进和删除。请看下面这段代码,它对一个长段落进行了包装。
import textwrap
s = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam pulvinar tellus sit amet libero viverra feugiat. Curabitur id ultrices metus. Donec lacinia, turpis et fermentum porta, nisl turpis eleifend orci, vel bibendum sapien massa et nisi'
print(textwrap.fill(s, width=50))
上述代码片段根据给定的宽度应用了换行字符,并打印出格式正确的段落,如下所示。
使用Python中的textwrap模块包装段落
该模块还提供了一个函数,可根据给定的字符数和后缀缩短长段落,如以下代码片段所示。
print(textwrap.shorten(s, 20, placeholder='...'))
# Lorem ipsum dolor...
Python还通过colorsys模块提供了几个颜色转换方便函数,用于在流行的颜色系统(如RGB、HSV等)之间转换颜色值。
请看下面的示例代码片段,它将HSV颜色值转换为RGB。
import colorsys
print(colorsys.hsv_to_rgb(1, 0.5, 0.2)) # (0.2, 0.1, 0.1)
该模块没有提供内置函数将这些0-1缩放的值转换为十六进制表示法,但你可以通过将值乘以255来轻松完成转换。
import colorsys
print('#%.2x%.2x%.2x' % tuple(round(x * 255) \
for x in colorsys.hsv_to_rgb(1, 0.5, 0.2))) # #331a1a