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

Python编程常用技巧,你知道几个?

时间:2023-03-11 23:43:55 科技观察

Python是现在的热门技能。很多人都想学习Python编程,甚至一些名人,比如知名房地产开发商潘石屹,也开始学习Python。网上也有很多关于Python编程的内容。本文总结了Python编程的一些常用技巧,帮助初学者快速上手。一、字符串处理技巧1、清理用户输入清理输入值是一个常见的程序需求。比如做大小写转换,验证输入字符的注入,通常可以使用Regex,通过编写正则表达式来完成特殊的任务。但是对于复杂的情况,可以使用一些小技巧,比如:user_input="This\nstringhas\tsomewhitespaces...\r\n"character_map={ord('\n'):'',ord('\t'):'',ord('\r'):None}在这个例子中,你可以看到空格字符“\n”和“\t”都被替换为空格,而“\r”被删除.这是一个简单的例子,我们也可以使用unicodedata包和combinein()函数生成大型映射表来生成映射来替换字符串。2.提示用户输入需要用户名和密码才能操作的命令行工具或脚本。要使用此功能,一个有用的技巧是使用getpass模块:importgetpassuser=getpass.getuser()password=getpass.getpass()这三行代码让我们可以优雅地交互以提醒用户输入密码并捕获当前系统输入的用户和密码,输入密码后会自动屏蔽显示,防止被盗。3.查找字符串频率如果需要查找与某些输入字符串相似的词,可以使用difflib来实现:importdifflibdifflib.get_close_matches('appel',['ape','apple','peach','puppy'],n=2)#return['apple','ape']difflib.get_close_matches会找到相似度最好的字符串。在此示例中,第一个参数与第二个参数匹配。提供了一个可选参数n,它指定要返回的匹配项的最大数量,设置为thr的参数截止值(默认值0.6)确定匹配字符串的分数。4、多行字符串中可以使用反斜杠Python:In[20]:multistr="select*fromtest\...:whereid<5"In[21]:multistrOut[21]:'select*fromtestwhereid<5'也可以用三个引号:In[23]:multistr="""select*fromtest...:whereid<5"""In[24]:multistrOut[24]:'select*testwhereid<5'以上methodsshare的问题是缺少正确的缩进,如果我们尝试缩进,它会在字符串中插入空格。所以最终的解决方案是将字符串拆分为多行,并将整个字符串括在括号中:In[25]:multistr=("select*frommulti_row"...:"whererow_id<5"...:"orderbyage")In[26]:multistrOut[26]:'select*frommulti_rowwhererow_id<5orderbyage'5.处理IP地址常用的套路之一就是验证匹配IP地址。这个功能有一个特殊的模块ipaddress。比如我们要使用IP网段(CIDR使用IP和掩码位)生成IP地址列表:importipaddressnet=ipaddress.ip_network('192.168.1.0/27')结果:#192.168.1.0#192.168.1.1#192.168.1.2#192.168.1.3#...另一个验证IP地址是否在IP段中的好功能:ip=ipaddress.ip_address("192.168.1.2")ipinnet#Trueip=ipaddress.ip_address("192.168.1.253")ipinnet#伪IP地址转字符串,整数转换:>>>str(ipaddress.IPv4Address('192.168.0.1'))'192.168.0.1'>>>int(ipaddress.IPv4Address('192.168.0.1'))3232235521>>>str(ipaddress.IPv6Address('::1'))'::1'>>>int(ipaddress.IPv6Address('::1'))1请注意,ipaddress还支持许多其他功能,例如如支持ipv4、ipv6等,具体请参考模块文档。二、性能优化技巧1、限制CPU和内存使用如果Python程序占用资源过多,想限制资源的使用,可以使用资源包。#CPU限制deftime_exceeded(signo,frame):print("CPUexcess...")raiseSystemExit(1)defset_max_runtime(seconds):soft,hard=resource.getrlimit(resource.RLIMIT_CPU)resource.setrlimit(resource.RLIMIT_CPU,(seconds,hard))signal.signal(signal.SIGXCPU,time_exceeded)#限制内存使用defset_max_memory(size):soft,hard=resource.getrlimit(resource.RLIMIT_AS)resource.setrlimit(resource.RLIMIT_AS,(size,hard))限制CPU时,首先获取特定资源(RLIMIT_CPU)的软限制和硬限制,然后使用参数指定的秒数和获取的硬限制进行设置。如果超过CPU时间,将记录导致系统退出的信号。对于内存限制,首先获取softlimit和hardlimit,通过setrlimit和size参数进行设置。2、通过__slots__节省内存如果程序中有一个类需要创建大量的实例,那么它可能会占用大量的内存。因为Python使用字典来表示类实例的属性,这加快了执行速度,但内存效率很低,通常这不是问题。__slots__可用于优化:importsysclassFileSystem(object):def__init__(self,files,folders,devices):self.files=filesself.folders=foldersself.devices=devicesprint(sys.getsizeof(FileSystem))classFileSystem1(object):__slots__=['files','folders','devices']def__init__(self,files,folders,devices):self.files=filesself.folders=foldersself.devices=devicesprint(sys.getsizeof(FileSystem1))#Python3.5下一步#1->1016#2->888在定义__slots__属性时,Python使用固定大小的数组作为属性而不是字典,这大大减少了每个实例所需的内存。当然使用__slots__也有缺点,比如不能声明任何新的属性,只能在__slots__上使用,__slots__的类不能使用多重继承。3.使用lru_cache缓存函数调用。据说Python性能很差,尤其是做一些计算的时候。其实解决程序性能问题有一些通用的方法,比如缓存和内存。在functools中使用lru_cache可以解决迭代计算中大量重复迭代调用的问题:#CacheInfo(hits=2,misses=4,maxsize=32,currsize=4)在上面的例子中,我们执行的GET请求是缓存(最多3个缓存结果)。还可以使用cache_info方法检查函数的缓存信息。装饰器还提供了一个clear_cache方法来删??除缓存。4.__all__控制一些语言支持导入成员(变量、方法、接口)的导入机制。在Python中,默认情况下会导入所有内容,但是可以使用__all__来限制defffoo():passdefbar():pass__all__=["bar"]这样我们就可以在使用fromsome_moduleimport*时限制可以导入的内容。在本例中,仅导入了bar函数。如果__all__留空并且在使用通配符导入时没有导入任何内容,则会触发AttributeError错误。三、面向对象1、创建支持With语句的对象我们都知道open或者close语句,比如打开文件或者获取锁,但是如何实现自己的方法呢?您可以使用__enter__和__exit__方法:#__enter__()executes...#conn.__exit__()executes这是在Python中实现上下文管理最常用的方法,但还有一种更简单的方法:fromcontextlibimportcontextmanager@contextmanagerdeftag(name):print(f"<{name}>")yieldprint(f"")withtag("h1"):print("ThisisTitle.")上面的代码片段使用contextmanager装饰器实现了内容管理协议。进入with块时,会执行标记函数的第一部分(在yield之前),然后执行块,最后执行标记函数的其余部分。2.重载运算符的技巧考虑到有很多比较运算符:__lt__、__le__、__gt__,一个类实现所有比较运算符可能很烦人。这时候可以使用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__需要定义。3.在一个类中定义多个构造函数函数重载是编程语言中非常常见的一个特性。尽管Python不能重载普通函数,但我们可以使用类方法重载构造函数:datetime.datetime.now()returncls(t.year,t.month,t.day)d=Date.today()print(f"{d.day}/{d.month}/{d.year}")#14/9/2019它可以通过不使用构造函数并将所有逻辑放入__init__并使用*args、**kwargs和一堆if语句来解决,但它很难看,不可读性和可维护性。4、获取对象信息Python提供了几个函数让我们可以更好的获取对象信息,这些函数包括:type、isinstance和dir。其中type():用于判断对象类型:>>>type(None)>>>type(abs)返回对应的类类型给类对象类型()。下面判断两个变量的type类型是否相同:>>>type(11)==type(22)True>>>type('abc')==strTrue>>>type('abc')==type(33)Falseisinstance():可以显示对象是否是某种类型>>>classHusty(Dog):...pass...>>>a=Animal()>>>b=Dog()>>>c=Husty()>>>isinstance(c,Husty)True>>>isinstance(c,Dog)True>>>isinstance(c,Animal)True>>>isinstance(b,Husty)FalseHusty是Husty,Dog,Animal类型的对象,但不能说Dog是Husty的对象。dir():用于获取一个对象的所有方法和属性。返回值是一个包含字符串的列表:>>>dir('abc')['__add__','__class__',...'__hash__','__init__','__i...'isalnum'isidentifier','islower',...'translate','upper','zfill']其中类似于__xx__的属性和方法是有特殊用途的。如果调用len()函数查看得到一个对象的长度,实际上len()函数内部会自动调用该对象的__len__()方法。5.Iterator和slice如果直接对Iterator进行slice,会报TypeError,指出generator对象不能下标,但是有个trick:importitertoolss=itertools.islice(range(50),10,20)forvalins:。..使用itertools.islice,您可以创建一个islice对象,它是一个产生所需项目的迭代器。然而,这会消耗所有生成器项目直到分片的开始,并且还会消耗islice对象中的所有项目。6.跳过一些行有时需要使用已知数量可变的不必要行(例如注释)。您还可以使用itertools:string_from_file="""//Author:...//License:...////Date:...Actualcontent..."""importitertoolsforlineinitertools.dropwhile(lambdaline:line.startswith("//"),string_from_file.split("\n")):print(line)此代码段仅在初始注释部分之后生成行。如果您只想在迭代器的开头丢弃并且不知道其中有多少项,这将很有用。7、对命名切片使用大量硬编码的索引值,容易造成代码繁琐,破坏代码可读性。一个常见的技巧是索引值使用常量,否则我们可以使用命名切片:在示例中,您可以看到可以通过先使用切片函数命名它们来进行索引,然后在切出一部分时使用它们字符串。还可以使用切片对象的属性.start、.stop和.step获取更多信息。四、调试技巧1.脚本调试Python脚本调试可以使用pdb模块。它允许我们在脚本中随意设置断点:importpdbpdb.set_trace()可以指定pdb.set_trace()在脚本的任意位置设置断点,非常方便。2.在shell中调试程序在shell中,可以使用python的-i选项可以启动一个交互环境,在这个环境中可以打印运行时变量值和调用函数的运行,比如下面的test.pyshell中的脚本deffunc():return0/0func()通过python-itest.py来运行我们导入pdb的脚本然后调用pdb.pm()启动调试器会把程序显示到崩溃的地方,我们退出程序并在那里设置一个断点:importpdb;deffunc():pdb.set_trace()return0/0func()再次运行它,它会停在断点处,并进入下一步。这样我们就可以对程序的执行进行调试和追溯。通过设置一个断点,然后当程序运行时,执行会停在断点处,可以检查程序,例如列出函数参数,评估表达式,列出变量或逐步执行等。5.有用小工具1.一键式web服务共享在Python中,可以使用http.server一键启用HTTP服务器。这是一个非常方便的分享工具:python-mhttp.server开启默认监听端口8000服务端可以自定义端口,比如8888python-mhttp.server8888代码自动补全JediJedi是Python代码自动补全和静态的库分析。Jedi允许我们高效地键入代码。目前Jedi已经提供了大部分的编辑器插件,包括Vim(jedi-vim)、VSC、Emacs、Sublime、Atom等。2.美化异常输出pretty-errorsPython默认的错误输出很乱,让人看起来很大,可读性差。这时候就需要用到pretty-errors错误美化工具了。结语在本文中,我们总结了一些Python日常使用中的常用技巧,希望能给大家一些帮助和启发。所有这些函数都在Python标准库中。在日常使用中,也建议大家尽量使用Python标准库,避免使用第三方库。