Python学习教程_Python学习路线:Python3里你不知道的秘密特性


概述

到2020年,Python2的官方维护期就要结束了,越来越多的Python项目从Python2切换到了Python3。其实在实际工作中,很多伙伴都还是在用Python2的思维写Python3的代码。小强给大家总结一下Python3一些新的更方便的特性!希望你们看完后也能高效率的编写代码


f-strings (3.6+)

在Python里面,我们经常使用format函数来格式化字符串,例如:

user="JaneDoe"action="buy"log_message='User{}hasloggedinanddidanaction{}.'.format(user,action)print(log_message)输出:UserJaneDoehasloggedinanddidanactionbuy.

Python3里面提供了一个更加灵活方便的方法来格式化字符串,叫做f-strings。上面的代码可以这样实现:

user="JaneDoe"action="buy"log_message=f'User{user}hasloggedinanddidanaction{action}.'print(log_message)输出:UserJaneDoehasloggedinanddidanactionbuy.

Pathlib (3.4+)

f-strings这个功能太方便了,但是对于文件路劲这样的字符串,Python还提供了更加方便的处理方法。Pathlib是Python3提供的一个处理文件路劲的库。例如:

frompathlibimportPathroot=Path('post_sub_folder')print(root)输出结果:post_sub_folderpath=root/'happy_user'#输出绝对路劲print(path.resolve())输出结果:/root/post_sub_folder/happy_user

Type hinting (3.5+)

静态与动态类型是软件工程中的一个热门话题,每个人都有不同的看法,Python作为一个动态类型语言,在Python3中也提供了Type hinting功能,例如:

defsentence_has_animal(sentence:str)->bool:return"animal"insentencesentence_has_animal("Donaldhadafarmwithoutanimals")#True

Enumerations (3.4+)

Python3提供的Enum类让你很容就能实现一个枚举类型:

fromenumimportEnum,autoclassMonster(Enum):ZOMBIE=auto()WARRIOR=auto()BEAR=auto()print(Monster.ZOMBIE)输出:Monster.ZOMBIE

Python3的Enum还支持比较和迭代。

formonsterinMonster:print(monster)输出:Monster.ZOMBIEMonster.WARRIORMonster.BEAR

Built-in LRU cache (3.2+)

缓存是现在的软件领域经常使用的技术,Python3提供了一个lru_cache装饰器,来让你更好的使用缓存。下面有个实例:

importtimedeffib(number:int)->int:ifnumber==0:return0ifnumber==1:return1returnfib(number-1)+fib(number-2)start=time.time()fib(40)print(f'Duration:{time.time()-start}s')#Duration:30.684099674224854s

现在我们可以使用lru_cache来优化我们上面的代码,降低代码执行时间。

fromfunctoolsimportlru_cache@lru_cache(maxsize=512)deffib_memoization(number:int)->int:ifnumber==0:return0ifnumber==1:return1returnfib_memoization(number-1)+fib_memoization(number-2)start=time.time()fib_memoization(40)print(f'Duration:{time.time()-start}s')#Duration:6.866455078125e-05s

Extended iterable unpacking (3.0+)

代码如下:

head,*body,tail=range(5)print(head,body,tail)输出:0[1,2,3]4py,filename,*cmds="python3.7script.py-n5-l15".split()print(py)print(filename)print(cmds)输出:python3.7script.py['-n','5','-l','15']first,_,third,*_=range(10)print(first,third)输出:02

Data classes (3.7+)

Python3提供data class装饰器来让我们更好的处理数据对象,而不用去实现init() 和repr()方法。假设如下的代码:

classArmor:def__init__(self,armor:float,description:str,level:int=1):self.armor=armorself.level=levelself.description=descriptiondefpower(self)->float:returnself.armor*self.levelarmor=Armor(5.2,"Commonarmor.",2)armor.power()#10.4print(armor)#<__main__.Armorobjectat0x7fc4800e2cf8>

使用data class实现上面功能的代码,这么写:

fromdataclassesimportdataclass@dataclassclassArmor:armor:floatdescription:strlevel:int=1defpower(self)->float:returnself.armor*self.levelarmor=Armor(5.2,"Commonarmor.",2)armor.power()#10.4print(armor)#Armor(armor=5.2,description='Commonarmor.',level=2)

Implicit namespace packages (3.3+)

通常情况下,Python通过把代码打成包(在目录中加入init.py实现)来复用,官方给的示例如下:

sound/Top-levelpackage__init__.pyInitializethesoundpackageformats/Subpackageforfileformatconversions__init__.pywavread.pywavwrite.pyaiffread.pyaiffwrite.pyauread.pyauwrite.py...effects/Subpackageforsoundeffects__init__.pyecho.pysurround.pyreverse.py...filters/Subpackageforfilters__init__.pyequalizer.pyvocoder.pykaraoke.py

在Python2里,如上的目录结构,每个目录都必须有init.py文件,一遍其他模块调用目录下的python代码,在Python3里,通过 Implicit Namespace Packages可是不使用__init__.py文件

sound/Top-levelpackage__init__.pyInitializethesoundpackageformats/Subpackageforfileformatconversionswavread.pywavwrite.pyaiffread.pyaiffwrite.pyauread.pyauwrite.py...effects/Subpackageforsoundeffectsecho.pysurround.pyreverse.py...filters/Subpackageforfiltersequalizer.pyvocoder.pykaraoke.py

结语

小强这里由于时间关系(确实挺忙)只列出了部分Python3的新功能,希望你在看了这篇文章以后,学以致用,写出更清晰更直观的代码!更多的Python学习教程和分享,小强后续会继续为大家更新!