即将开播: 5 月 14 日, Jenkins 在 K8S 下的三种部署流程和实战演示
有很多介绍 Python 中各种很酷的功能 (如变量拆包, 偏函数, 枚举可迭代对象) 的文章, 但说到 Python 时, 还有很多东西可以谈论, 这里我将尝试展示我所知道和使用的一些特性, 我还没有在其他地方看到有人提到过它们. 我们开始吧.
清理字符串输入
对用户输入进行清理的问题几乎适用于您编写的所有程序. 通常情况下, 将字符转换为小写或大写就足够了, 有时您可以使用 Regex 来完成这项工作, 但对于复杂的情况来说, 可能有更好的方法:
在本例中, 您可以看到空白字符 "\n" 和 "\t" 已被单个空格替换, 而 "\r" 已被完全删除. 这是一个简单的例子, 但是我们可以更进一步, 使用 unicodedata 包和它的 combining()函数来生成并进行映射, 从而生成更大的重新映射表, 我们可以使用它来删除字符串中的所有重音.
对迭代器进行切片
如果您尝试对一个迭代器进行切片, 您会得到一个 TypeError, 这说明生成器对象是不可下标访问的, 但有一个简单的解决方案可以解决这个问题:
使用 itertools.islice 我们可以创建一个 islice 对象, 它是一个会生成所需项的迭代器. 需要注意的是, 这将消耗 slice 开始之前的所有生成器项, 以及 islice 对象中的所有项.
跳过可迭代对象的开始部分
有时您必须处理那些以您不想要的可变数量的行 (如注释) 开始的文件. itertools 再次为这个问题提供了简单的解决方案:
这代码段只生成初始注释部分之后的行. 如果我们只想在可迭代对象的开头丢弃一些项目(本例中是一些行), 并且不知道有多少个项目, 那么这种方法是很有用的.
只带有关键字参数 (kwargs) 的函数
在使用以下这样的函数时, 创建只接受关键字参数的函数来提供 (强制) 更多的清晰性是很有帮助的:
正如您所看到的, 这可以通过在关键字参数之前放置单个 * 参数来轻松解决. 如果我们把位置参数放在 * 参数之前, 位置参数显然也会存在.
创建支持 with 语句的对象
例如, 我们都知道如何使用 with 语句来打开文件或获取锁, 但是我们可以实现自己的 with 语句吗? 当然, 我们可以使用__enter__和__exit__方法来实现上下文管理协议:
这是在 Python 中实现上下文管理最常见的方法, 但是还有更简单的实现方法:
上面的代码片段使用 contextmanager 管理器装饰器实现了内容管理协议. 在进入 with 块时, tag 函数 (在 yield 之前) 的第一部分会被执行, 然后该 with 块被执行, 最后, tag 函数的其余部分会被执行.
使用__slots__节省内存
如果您曾经编写过一个创建某个类的大量实例的程序, 您可能会注意到您的程序会突然需要大量内存. 这是因为 Python 使用字典来表示类实例的属性, 这使得它的速度很快, 但是内存效率不高, 这通常并不是一个问题. 然而, 如果它成为您的程序的一个问题时, 您可以尝试使用__slots__:
这里的情况是, 当我们定义了__slots__属性时, Python 会使用小的固定大小的数组而不是字典来定义属性, 这大大减少了每个实例所需的内存. 使用__slots__也有一些缺点 -- 我们不能声明任何新的属性, 并且我们只能使用在__slots__上这些属性. 而且, 带有__slots__的类不能使用多重继承.
限制 CPU 和内存的使用
如果您不想优化您的程序内存或 CPU 使用, 您只想把它限制在某个固定大小的内存上, 那么 Python 也有一个这样的库来做到这一点:
这里我们可以看到设置最大 CPU 运行时间和最大内存使用限制的两个选项. 对于 CPU 限制, 我们首先获取特定资源 (RLIMIT_CPU) 的软限制和硬限制, 然后使用参数指定的秒数和前面检索到的硬限制来设置它. 最后, 我们注册信号, 如果 CPU 时间超过限制, 该信号会导致系统退出. 对于内存, 我们再次检索软限制和硬限制, 并使用带有大小参数的 setrlimit 和检索的硬限制来设置它.
控制什么可以导入, 什么不可以导入
一些语言有非常明显的导出成员 (变量, 方法, 接口) 的控制机制, 例如 Golang, 其中只有以大写字母开头的成员会被导出. 另一方面, 在 Python 中, 所有东西都可以被导出, 除非我们使用__all__:
根据上面的代码片段, 我们知道只有 bar 函数会被导出. 同样, 我们可以让__all__为空, 这样, 当我们从这个模块导入的时候, 任何东西都不会被导出, 并且会导致 AttributeError.
实现比较运算符的简单方式
考虑到目前已经有相当多的比较操作符 --__lt__ ,__le__ , __gt__ 或 __ge___, 因此, 为一个类实现所有的比较操作符是相当烦人的. 但如果有更简单的方法可以实现呢? functools.total_ordering 就派上用场了:
那么, 这到底是怎么工作的呢? total_ordering 装饰器用于简化实现类实例排序的过程. 我们只需要定义__lt__和__eq__, 它们是剩余操作的映射所需的最小值, 装饰器就会为我们填充空白.
结论
并不是所有这些特性在日常的 Python 编程中都是必需的和有用的, 但是它们中的一些可能会不时地派上用场, 而且它们还可能会简化那些在其他情况下会非常冗长和难以实现的任务. 我也想说明的是, 所有这些特性是 Python 标准库的一部分, 而其中的一些在我看来就像标准库中所具有的相当不标准的东西, 所以当您想使用 Python 实现某些东西的时候, 您首先应该去标准库中寻找它, 如果您不能找到它, 那么您可能还是不够努力(如果真的没有, 那它肯定在一些第三方库中).
来源: http://developer.51cto.com/art/202005/616189.htm