Python高效率的技巧
你估计已经看了不少关于Python技巧的文章,里面可能会提到变量拆包(unpacking)、局部函数等,但是Python还有很多不为人知的高效用法,等待着被人发现。本文将介绍作者纵观全网之后,都属于很少没提及的技巧。
清理字符串输入
清理用户输入的问题,几乎适用于我们可能编写的每个程序。通常将字符转换为小写或大写就足够了,这时只需要使用正则即可,但是对于复杂的情况,有一种更好的方法:
user_input="This\nstringhas\tsomewhitespaces...\r\n"
character_map={
ord('\n'):'',
ord('\t'):'',
ord('\r'):None
}
user_input.translate(character_map)#Thisstringhassomewhitespaces..."
在上述示例中,可以看到空格符“\n”和“\t”已被单个空格替换,而“\r”已被完全删除。这是一个简单的示例,但是我们可以更进一步,使用unicodedata包及其combining()函数生成范围更广的映射表,从字符串中删除所有重音符号。
迭代器切片
如果您尝试获取迭代器的切片,系统会报TypeError,提示生成器对象不可下标,但是解决方案很简单:
importitertools
s=itertools.islice(range(50),10,20)#
forvalins:
...
使用itertools.islice,我们可以创建一个islice对象,该对象是产生所需元素的迭代器。不过,请务必注意,这会消耗所有生成器项,直到切片开始为止,而且还会消耗我们的“islice”对象中的所有项。
Usingitertools.islicewecancreateaisliceobjectwhichisaniteratorthatproducesdesireditems.It'simportanttonotethough,thatthisconsumesallgeneratoritemsupuntilthestartofsliceandalsoalltheitemsinourisliceobject.
跳过可迭代对象的开始
有时候需要处理的文件里,明确存在一些不需要的数据行,但是我们不确定数量,比如说代码中的注释。这时,itertools再次为我们提供了简洁的方案:
string_from_file="""
//Author:...
//License:...
//
//Date:...
Actualcontent...
"""
importitertools
forlineinitertools.dropwhile(lambdaline:line.startswith("//"),string_from_file.split("\n")):
print(line)
这段代码仅在初始注释部分之后,才会产生数据行。如果我们只想在迭代器的开头丢弃数据,而又不知道有具体数量时,这个方法很有用。
仅带关键字参数(kwargs)的函数
有时候,使用仅支持关键字参数的函数可以让代码更加清晰易懂:
deftest(*,a,b):
pass
test("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
上面是最常见的实现方式,但是还有一种更简单的方法:
fromcontextlibimportcontextmanager
@contextmanager
deftag(name):
print(f"<{name}>")
yield
print(f"")
withtag("h1"):
print("ThisisTitle.")
上面的代码段使用contextmanager管理器装饰器实现了内容管理协议。进入“with”块时,执行“tag”函数的第一部分(在“yield”之前),然后执行yield,最后执行其余部分。
用__slots__节省内存
如果程序需要创建大量的类实例,我们会发现程序占用了大量内存。这是因为Python使用字典来表示类实例的属性,这样的话创建速度很快,但是很耗内存。如果内存是你需要考虑的一个问题,那么可以考虑使用__slots__:
classPerson:
__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也有一个可以满足要求的库:
importsignal
importresource
importos
#ToLimitCPUtime
deftime_exceeded(signo,frame):
print("CPUexceeded...")
raiseSystemExit(1)
defset_max_runtime(seconds):
#Installthesignalhandlerandsetaresourcelimit
soft,hard=resource.getrlimit(resource.RLIMIT_CPU)
resource.setrlimit(resource.RLIMIT_CPU,(seconds,hard))
signal.signal(signal.SIGXCPU,time_exceeded)
#Tolimitmemoryusage
defset_max_memory(size):
soft,hard=resource.getrlimit(resource.RLIMIT_AS)
resource.setrlimit(resource.RLIMIT_AS,(size,hard))
在这里,我们可以设置了最大cpu运行时间以及最大内存使用限制的两个选项。对于cpu限制,我们首先获得该特定资源(RLIMIT_CPU)的软限制和硬限制,然后使用参数指定的秒数和先前获取的硬限制来设置。
最后,我们注册了一个在超过CPU时间后,让系统退出的信号。至于内存,我们再次获取软限制和硬限制,并使用带有大小参数的setrlimit和硬限制完成配置
控制导入的内容
某些语言提供了导出成员(变量,方法,接口)的显式机制,例如Golang,它仅导出以大写字母开头的成员。但是在Python中,所有对象都会导出,除非我们使用__all__:
deffoo():
pass
defbar():
pass
__all__=["bar"]
上面的代码段中,只会导出bar函数。另外,如果__all__的值为空,那么不会导出任何函数,而且在导入该模块时系统会报AttributeError。
实现比较运算符
如果我们要逐一为某个类实现所有的比较运算符,你肯定会觉得很麻烦,因为要实现的方法还不少,有__lt__,__le__,__gt__,和__ge__。
其实,Python提供了一种便捷的实现方式,就是通过functools.total_ordering装饰器。
fromfunctoolsimporttotal_ordering
@total_ordering
classNumber:
def__init__(self,value):
self.value=value
def__lt__(self,other):
returnself.value def__eq__(self,other): returnself.value==other.value print(Number(20)>Number(3)) print(Number(1) print(Number(15)>=Number(15)) print(Number(10)<=Number(2)) 这是怎么实现的呢?total_ordering可以用来简化实现类排序的过程。我们只需要定义__lt__和__eq__(这是映射剩余操作的最低要求),然后就交给装饰器去完成剩余的工作了。 结语 在日常Python编程时,上述特性并非都是必不可少的和有用的,但是其中某些功能可能会不时派上用场,并能简化冗长且令人讨厌的任务。 还要指出的是,所有这些功能都是Python标准库的一部分,而在我看来,其中一些功能似乎不像是应该在标准库中的功能。 因此,每当你决定要用Python实现某些功能时,都请先在标准库中找一找,如果找不到合适的库,那么可能是因为查找的姿势不对。而且即使标准库里没有,有很大的概率已经存在一个第三方库了! 以上内容为大家介绍了Python高效率的技巧,希望对大家有所帮助,如果想要了解更多Python相关知识,请关注IT培训机构:千锋教育。http://www.mobiletrain.org/
相关推荐HOT
更多>>python变量赋值是什么
1、什么是变量?变量:值会发生变化的的量,与常量相对.2、python支持的变量数据类型:Python有五个标准的数据类型:1.数字2.字符串3.元组4.列表...详情>>
2023-11-06 23:04:12python实现线程安全的单例模式
详情>>
2023-11-06 20:23:17Python可执行文件和模块
python源代码文件按照功能可以分为两种类型:用于执行的可执行程序文件不用与执行,仅用于被其它python源码文件导入的模块文件例如文件a.py和b....详情>>
2023-11-06 17:27:50Python如何玩转加密?
python中的一个有用的基本加密库就叫做cryptography。它既是一个“安全”方面的基础库,也是一个“危险”层。“危险”层需要更加小心和相关的知...详情>>
2023-11-06 14:53:13