概述
随着Python在机器学习和数据科学领域的应用越来越广泛,相关的Python库也增长的非常快。但是Python本身存在一个非常要命的问题,就是Python2和Python3,两个版本互不兼容,而且Github上Python2的开源库有很多不兼容Python3,导致大量的Python2的用户不愿意迁移到Python3。
Python3在很多方面都做出了改变,优化了Python2的很多不足,标准库也扩充了很多内容,例如协程相关的库。现在列举一些Python3里提供的功能,跟你更好的从Python2迁移到Python3的理由。
系统文件路径处理库:pathlib
使用Python2的同学,应该都用过os.path这个库,来处理各种各样的路径问题,比如拼接文件路径的函数:os.path.join()
,用Python3,你可以使用pathlib很方便的完成这个功能:
from pathlib import Path
dataset = 'wiki_images'
datasets_root = Path('/path/to/datasets/')
train_path = datasets_root / dataset / 'train'
test_path = datasets_root / dataset / 'test'
for image_path in train_path.iterdir():
with image_path.open() as f: # note, open is a method of Path object
# do something with an image
相比与os.path.join()
函数,pathlib更加安全、方便、可读。pathlib还有很多其他的功能。
p.exists()
p.is_dir()
p.parts()
p.with_name('sibling.png') # only change the name, but keep the folder
p.with_suffix('.jpg') # only change the extension, but keep the folder and the name
p.chmod(mode)
p.rmdir()
类型提醒: Type hinting
在Pycharm中,类型提醒是这个样子的:
![](http://7xpx6h.com1.z0.glb.clouddn.com/bd231966d3936432ed6ef90b416e4a19
)
类型提醒在复杂的项目中可以很好的帮助我们规避一些手误或者类型错误,Python2的时候是靠IDE来识别,格式IDE识别方法不一致,并且只是识别,并不具备严格限定。例如有下面的代码,参数可以是numpy.array , astropy.Table and astropy.Column, bcolz, cupy, mxnet.ndarray等等。
def repeat_each_entry(data):
""" Each entry in the data is doubled
<blah blah nobody reads the documentation till the end>
"""
index = numpy.repeat(numpy.arange(len(data)), 2)
return data[index]
同样上面的代码,传入pandas.Series类型的参数也是可以,但是运行时会出错。
repeat_each_entry(pandas.Series(data=[0, 1, 2], index=[3, 4, 5])) # returns Series with Nones inside
这还只是一个函数,对于大型的项目,会有好多这样的函数,代码很容易就跑飞了。所以确定的参数类型对于大型项目来说非常重要,而Python2没有这样的能力,Python3可以。
def repeat_each_entry(data: Union[numpy.ndarray, bcolz.carray]):
目前,比如JetBrains家的PyCharm已经支持Type Hint语法检查功能,如果你使用了这个IDE,可以通过IDE功能进行实现。如果你像我一样,使用了SublimeText编辑器,那么第三方工具mypy可以帮助到你。
PS:目前类型提醒对ndarrays/tensors支持不是很好。
运行时类型检查:
正常情况下,函数的注释处理理解代码用,其他没什么用。你可以是用enforce
来强制运行时检查类型。
@enforce.runtime_validation
def foo(text: str) -> None:
print(text)
foo('Hi') # ok
foo(5) # fails
@enforce.runtime_validation
def any2(