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

高级编程之道:PythonTips

时间:2023-03-19 16:49:05 科技观察

介绍Python很酷的特性(比如变量拆包、偏函数、枚举可迭代对象等)的文章层出不穷。但是有很多Python编程小技巧很少被提及。因此,本文会尝试介绍一些在其他文章中没有提到的技巧,而这些技巧也是我平时使用的。让我们找出答案!整理字符串输入整理用户输入的问题在编程中极为常见。通常,将字符转换为小写或大写就足够了,有时您可以使用正则表达式模块“Regex”来完成这项工作。但如果问题比较复杂,可能有更好的解决方法:user_input="This\nstringhas\tsomewhitespaces...\r\n"character_map={ord('\n'):'',ord('\t'):'',ord('\r'):None}user_input.translate(character_map)#Thisstringhasssomewhitespaces...在这个例子中,你可以看到空格字符“\n”和“\t”是replaced变为单个空格,“\r”被删除。这只是一个很简单的例子,我们可以更进一步,使用“unicodedata”包生成一个大的重映射表,并使用其中的“combining()”来生成和映射,我们可以迭代切片(Slice)如果迭代生成器进行切片操作,会返回一个“TypeError”,说明生成器对象没有下标,但是我们可以用一个简单的方案来解决这个问题:importitertoolss=itertools.islice(range(50),10,20)#<itertools.isliceobjectat0x7f70fab88138>forvalins:...我们可以使用“itertools.islice”来创建一个“islice”对象,它是一个迭代器,可以产生我们想要的项目。但是请注意,此操作会消耗直到切片的所有生成器项,以及“islice”对象中的所有项。跳过可迭代对象的开头有时您必须处理以不需要的行开头的文件,例如注释。“itertools”再次提供了一个简单的解决方案:string_from_file="""//Author:...//License:...////Date:...Actualcontent..."""importitertoolsforlineinitertools。dropwhile(lambdaline:line.startswith("//"),string_from_file.split("\n")):print(line)这段代码只打印初始注释部分之后的内容。如果我们只想丢弃iterable的开头(在本例中为开始的注释行),但我们不知道我们希望它有多长,这很有用。仅包含关键字参数的函数(kwargs)创建仅需要关键字参数作为输入的函数有助于在我们使用以下函数时提供更清晰的函数定义:deftest(*,a,b):passtest("valuefora","valueforb")#TypeError:test()takes0positionalarguments...test(a="value",b="value2")#Works...可以看到,加上最后一个“*”就可以解决这个问题。如果我们把一些参数放在“*”参数之前,显然是位置参数。创建一个支持“with”语句的对象比如,我们都知道如何使用“with”语句打开文件或获取锁,但是我们可以实现自己的上下文表达式吗?是的,我们可以使用“__enter__”和“__exit__”来实现上下文管理协议:classConnection:def__init__(self):...def__enter__(self):#Initializeconnection...def__exit__(self,type,value,traceback):#Closeconnection...withConnection()asc:#__enter__()executes...#conn.__exit__()executes这是在Python中实现上下文管理最常用的方法,但还有更简单的方法:fromcontextlibimportcontextmanager@contextmanagerdeftag(name):print(f"<{name}>")yieldprint(f"")withtag("h1"):print("ThisisTitle.")上面的代码使用上下文管理器的装潢经理。标签函数的第一部分(yield之前的部分)在进入with块时执行,然后执行with块,最后执行标签函数的其余部分。使用“__slots__”节省内存如果您曾经编写过创建某个类的大量实例的程序,您可能已经注意到您的程序突然需要大量内存。那是因为Python使用字典来表示类实例的属性,这使得它速度很快,但内存效率不是很高。通常,这不是一个严重的问题。然而,如果你的程序受此严重影响,试试“__slots__”:last_name=last_nameself.phone=phone当我们定义“__slots__”属性时,Python没有使用字典来表示属性,而是使用了一个固定大小的小数组,这大大减少了每个实例所需的内存。使用“__slots__”也有一些缺点:我们不能声明任何新属性,我们只能使用“__slots__”上的现有属性。此外,带有“__slots__”的类不能使用多重继承。限制“CPU”和内存使用。如果你不想优化程序的内存或CPU使用率,而是想直接限制在一定数量,Python也有相应的库可以做到:importsignalimportresourceimportos#ToLimitCPUtimedeftime_exceeded(signo,frame):print("CPUexceeded...")raiseSystemExit(1)defset_max_runtime(seconds):#Installthesignalhandlerandsetaresourcelimitsoft,hard=resource.getrlimit(resource.RLIMIT_CPU)resource.setrlimit(resource.RLIMIT_CPU,(seconds,hard))signal.signal(signal.SIGXCPU,time_exceeded)#Tolimitmemoryusagedefset_max_memory(size):soft,hard=resource.getrlimit(resource.RLIMIT_AS)resource.setrlimit(resource.RLIMIT_AS,(size,hard))我们可以看到在上面的代码中Fragment包含设置最大CPU运行时间的选项和最大内存使用限制。在限制CPU的运行时间时,我们首先获取该特定资源(RLIMIT_CPU)的软硬限制,然后将它们设置为通过参数指定的秒数和先前检索到的硬限制。最后,如果CPU运行时间超过限制,我们将向系统发出退出信号。在内存使用方面,我们再次检索软硬限制,并使用带有“size”参数的“setrlimit”和先前检索到的硬限制来设置它。控制什么可以/不能导入一些语言有非常明显的导出成员(变量、方法、接口)的机制,例如在Golang中只导出以大写字母开头的成员。但是,在Python中,所有成员都被导出(除非我们使用“__all__”):defffoo():passdefbar():pass__all__=["bar"]在上面的代码中,我们知道只有“bar”函数被导出。同样,我们可以将“__all__”设为空,以便不导出任何内容,并在从该模块导入时引发“AttributeError”。实现比较运算符的简单方法为一个类实现所有比较运算符(如__lt__、__le__、__gt__、__ge__)是乏味的。有没有更简单的方法来做到这一点?“functools.total_ordering”在这种情况下是个好帮手:fromfunctoolsimporttotal_ordering@total_orderingclassNumber:def__init__(self,value):self.value=valuedef__lt__(self,other):returnsself.valueNumber(3))print(Number(1)=Number(15))print(Number(10)<=Number(2))这是如何工作的?我们使用“total_ordering”装饰器来简化对类实例进行排序的过程。我们只需要定义“__lt__”和“__eq__”,这是实现其余操作所需的最小操作集(这里也体现了装饰器的作用——为我们填空)。结论并非本文提到的所有特性在日常Python编程中都是必需的或有用的,但其中一些特性可能会不时派上用场,它们还可能简化一些原本乏味和烦人的任务。还值得指出的是,所有这些函数都是Python标准库的一部分。在我看来,其中一些功能似乎并不是标准库中包含的标准内容,所以当你使用Python实现本文提到的一些功能时,请先参考Python的标准库,如果不会的话findwhatyouwant可能只是你查得不够多(如果不存在,那一定是某个第三方库中有)。原文链接:https://medium.com/m/global-identity?redirectUrl=https%3A%2F%2Ftowardsdatascience.com%2Fpython-tips-and-trick-you-havent-already-seen-37825547544f【本文为专栏《机器之心》组织原译,微信公众号《机器之心(id:almosthuman2014)》】点此查看作者更多好文