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/
猜你喜欢LIKE
相关推荐HOT
更多>>python中的filter函数功能是什么?
python中的filter函数功能是什么?在python中,面对众多的数据,我们要过滤筛选出我们需要的数据。python中的filter函数就是起到了过滤筛选的作...详情>>
2023-11-10 20:37:27pythontime模块是什么
pythontime模块是什么在python中使用时间,就免不了和time模块打交道,另外两个模块这个暂时先不做介绍。做time模块的使用上,我们可以用它来对...详情>>
2023-11-10 15:53:16python是什么编程语言
python是什么编程语言1、说明是一种面向对象、解释型计算机程序设计语言,由GuidovanRossum于1989年底发明,第一个公开发行版发行于1991年。Pyt...详情>>
2023-11-10 15:21:05python异常处理的两种技巧
python异常处理的两种技巧1、传递异常有时我们会在捕捉到一个异常后重新引发它(传递异常),实现起来很简单,使用不带参数的raise语句即可。deff...详情>>
2023-11-10 14:49:39热门推荐
python中的filter函数功能是什么?
沸python delattr函数如何使用?
热python中pdb模块怎么用?
热Python如何截图保存?
新python中缺少module怎么办?
python strftime和strptime的不同分析
python time.strptime的格式化
python中@contextmanager是什么?
python对象的三要素是什么
pythonGIL在Python多线程的应用
python如何对多个CSV文件进行读取
pythonif嵌套命令如何理解?
python对列表进行永久性或临时排序的方法
python生成器调用方法引发异常