当前位置: 首页 > 科技观察

9LittleKnownPythonTricks

时间:2023-03-13 16:42:06 科技观察

介绍Python中各种炫酷特性(比如变量拆包、偏函数、枚举可迭代对象)的文章很多,但是说到Python,就多说说了,和在这里,我将尝试展示一些我所知道和使用的功能,这些功能我在其他任何地方都没有提到过。让我们开始吧。清理字符串输入清理用户输入的问题几乎适用于您编写的任何程序。通常将字符转换为小写或大写就足够了,有时你可以使用Regex来完成这项工作,但对于复杂的情况可能有更好的方法:在这个例子中你可以看到空白字符“\n”和“\t”"已被替换为单个空格,而"\r"已被完全删除。这是一个简单的例子,但我们可以更进一步,使用unicodedata包和它的combining()函数来生成和映射,从而得到一个更大的重映射表,我们可以用它来去除字符串中的所有重音符号。切片迭代器如果您尝试对迭代器进行切片,您将得到一个TypeError,指出生成器对象不可订阅,但是有一个简单的解决方案可以解决这个问题:使用itertools.islice我们可以创建一个islice对象,它是一个迭代器产生所需的项目。请注意,这将消耗切片开始之前的所有生成器项,以及islice对象中的所有项。跳过iterables的开头有时您必须处理以您不想要的可变行数(如注释)开头的文件。itertools再次为这个问题提供了一个简单的解决方案:这个代码片段只在初始评论部分之后生成行。如果我们只想在可迭代对象的开头丢弃一些项目(在这种情况下为行),并且不知道有多少,这种方法很有用。仅采用关键字参数的函数(kwargs)创建仅采用关键字参数的函数有助于在使用如下函数时提供(强制)更多清晰度:这可以通过在关键字参数之前放置一个*参数来轻松解决。如果我们把位置参数放在*参数之前,位置参数显然也会出现。创建支持with语句的对象例如,我们都知道如何使用with语句打开文件或获取锁,但是我们可以实现自己的with语句吗?当然,我们可以使用__enter__和__exit__方法来实现上下文管理协议:这是在Python中实现上下文管理最常见的方式,但还有更简单的方法:上面的代码片段使用contextmanager管理器装饰器。在进入with块时,执行标记函数的第一部分(在yield之前),然后执行with块,最后执行标记函数的其余部分。使用__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中实现某些东西时,有时,你应该先在标准库里找,如果找不到,那可能是你努力不够(如果真的没有,那肯定是在某个第三方库里)。