August Rush

一个还在努力成长的小火汁!

游龙当归海,海不迎我自来也。

We create our own demons.

You can reach me at augustrush0923@gmail.com
pathlib -- 一个更好用的path库
发布:2020年09月16日 | 作者:augustrush | 阅读量: 836

前言

今天准备开荒Django 3.1,随即便pip install django==3.1 & django-admin startproject DjangoProject。尔后打开settings.py一看,第一行代码就让我不知所措(强行劝退?)

BASE_DIR = Path(file).resolve().parent.parent


这Path是个什么鬼???,马上翻开python文档查看资料。现来总结一下Path的方法

基本用法


In : from pathlib import Path

In : p = Path('/User/augustrush/Desktop')

In : p
Out: PosixPath('/User/augustrush/Desktop')

In : str(p)
Out: '/User/augustrush/Desktop'


使用str函数可以把一个Path对象转化成字符串。在Python 3.6之前,Path对象是不能作为os模块下的参数的,需要手动转化成字符串 从Python 3.6开始,这些接受路径作为参数的函数内部会先通过os.fspath调用Path对象的__fspath__方法获得字符串类型的路径再去执行下面的逻辑。

和os功能对应的方法列表

os & os.path pathlib
os.path.abspath Path.resolve
os.chomd Path.chmod
os.mkdir Path.mkdir
os.rename Path.rename
os.replace Path.replace
os.rmdir Path.rmdir
os.remove Path.unlink
os.getcwd Path.cwd
os.path.exists Path.exists
os.path.expanduser Path.expanduser & Path.home
os.path.isdir Path.is_dir
os.path.isfile Path.is_file
os.path.islink Path.is_symlink
os.stat Path.stat, Path.owner, Path.group
os.path.isabs PurePath.is_absolute
os.path.join PurePath.joinpath
os.path.basename PurePath.name
os.path.dirname PurePath.parent
os.path.samefile Path.samefile
os.path.splitext PurePath.suffix


# 原来的写法
In : os.path.isdir(os.getcwd())
Out: True
# 新的写法
In : Path.cwd().is_dir()
Out: True

# 原来的写法
In : os.path.basename('/usr/local/etc/mongod.conf')
Out: 'mongod.conf'
# 新的写法
In : Path('/usr/local/etc/mongod.conf').name
Out: 'mongod.conf'


/拼接路径


过去路径拼接最正确的方法是用os.path.join:

In : os.path.join('/', 'User', 'augustrush/Desktop')
Out: '/User/augustrush/Desktop'

In : os.path.join('/User', 'augustrush/Desktop')
Out: '/User/augustrush/Desktop'


现在可以用pathlib.Path提供的joinpath来拼接:

In : Path('/').joinpath('User', 'augustrush/Desktop')
Out: PosixPath('/User/augustrush/Desktop')


但是更简单和方便的方法是用/运算符:

In : Path('/') / 'User' / 'augustrush/Desktop'
Out: PosixPath('/home/augustrush/Desktop')

In : Path('/') / Path('User') / 'augustrush/Desktop'
Out: PosixPath('/User/augustrush/Desktop')

In : '/' / Path('User') / 'augustrush/Desktop'
Out: PosixPath('/User/augustrush/Desktop')


链式调用


链式调用是OOP带来的重要改变,从前面的例子中也能感受到,过去的都是把路径作为函数参数传进去,现在可以链式调用。我们看一个更复杂一点的例子:

In : os.path.isfile(os.path.join(os.path.expanduser('~/lyanna'), 'config.py'))
Out: True


长不长?现在的写法呢:

In : (Path('~/lyanna').expanduser() / 'config.py').is_file()
Out: True


是不是非常符合我们从左向右的阅读习惯呢?

自带属性


Path对象带了多个有用的属性

drive, name

drive: 一个表示驱动器盘符或命名的字符串,如果存在

In : p = Path('D:\\project\\Aridea\\Aridea\\config.tar.bz2')
In : p.drive
Out: 'D:'

In : Path('/User/augustrush').drive
Out: ''

In : Path(r'\\servername\sharename\directory\filename').drive  # UNC 分享也被认作驱动器:
Out: '\\\\servername\\sharename'


name: 一个表示最后路径组件的字符串,排除了驱动器与根目录,如果存在的话:

In : p = Path('/Users/augustrush/Desktop/JapenAv.avi')
In : p.name
Out: 'JapenAv.avi'


parent & parents


如果想获得某个文件的父级目录,那就可以用parent or parents
使用Path对象的parents属性可以拿到各级目录列表(索引值越大越接近root),而parent就表示父级目录:

In : p = Path('/Users/augustrush/Desktop')

In : p.parents
Out: <PosixPath.parents>

In : for i in p.parents:
         print(i)
Out: /Users/augustrush
     /Users
     /

In : p.parents[0]
Out: PosixPath('/Users/augustrush/')

In : p.parents[1]
Out: PosixPath('/Users')

In : p.parents[2]
Out: PosixPath('/')

In : p.parent
Out: PosixPath('/Users/dongweiming')

In : p.parent.parent # 由于parent返回的还是Path对象,所以可以链式的获取其parent属性。
Out: PosixPath('/Users')


suffix(es)/stem


获得文件后缀名,以及去掉后缀的文件名字

In : p = Path('/usr/local/etc/my.cnf')

In : p.suffix, p.stem
Out: ('.cnf', 'my')


当文件有多个后缀,可以用suffixes返回文件所有后缀列表:

In : Path('my.tar.bz2').suffixes
Out: ['.tar', '.bz2']

In : Path('my.tar').suffixes
Out: ['.tar']

In : Path('my').suffixes
Out: []


方法

Path.resolve(strict=False)


将路径绝对化,解析任何符号链接。返回新的路径对象:

In : Path().resolve()
Out: WindowsPath('D:/project/Aridea')

In : Path()
Out: PosixPath('.')

In : p.resolve()
Out: PosixPath('/home/augustrush')


Path.glob(pattern)与Path.rglob(pattern)

Path.glob(pattern):获取路径下的所有符合pattern的文件,返回一个generator

In : list(Path().glob('*.py'))
Out: [WindowsPath('manage.py')]


Path.rglob(pattern):与上面类似,只不过是返回路径中所有子文件夹的符合pattern的文件。

In : list(Path().rglob('*.py'))
Out: [WindowsPath('manage.py'), WindowsPath('Aridea/asgi.py'), WindowsPath('Aridea/settings.py'), WindowsPath('Aridea/urls.py'), WindowsPath('Aridea/wsgi.py'), WindowsPath('Aridea/__init__.py')]


Path.chmod(mod)

改变文件的模式和权限,和 os.chmod() 一样:

In : p = Path('setup.py')
In : p.stat().st_mode
Out: 33277
In : p.chmod(0o444)
In : p.stat().st_mode
Out: 33060


Path.mkdir(mode=0o777, parents=False, exist_ok=False)


根据路径创建文件夹

如果给出了 mode ,它将与当前进程的 umask 值合并来决定文件模式和访问标志。

如果parents=True时,会依次创建路径中间缺少的文件夹。如果 parents = false(默认),则找不到的父级目录会导致 FileNotFoundError 被抛出。

如果 exist_ok = false(默认),则在目标已存在的情况下抛出 FileExistsError

p_new = Path('new_dir')
p_new.mkdir()

p_news = Path('new_dirs/new_dir')
p_news.mkdir(parents=True)


Path.rename(target)


当target是string时,重命名文件或文件夹

当target是Path时,重命名并移动文件或文件夹

p1 = Path('1.py')
p1.rename('new_name.py')

p2 = Path('11.py')
target = Path('new_dir/new_name.py')
p2.rename(target)


Path.replace(target)


重命名当前文件或文件夹,如果target所指示的文件或文件夹已存在,则覆盖原文件

在 3.8 版更改: 添加了返回值,返回新的 Path 实例。

Path.rmdir()


移除此目录。此目录必须为空的。

Path.unlink(missing_ok=False)


移除此文件或符号链接。如果路径指向目录,则用 Path.rmdir() 代替。

Path.cwd()


获取当前路径

Path.exists()

判断当前路径的文件或者文件夹是否存在

In : Path('.').exists()
Out: True
In : Path('1.py').exists()
Out:True
In : Path('2.py').exists()
Out:False

如果路径指向一个符号链接, exists() 返回此符号链接是否指向存在的文件或目录。

Path.expanduser() & Path.home()


Path.expanduser()返回展开了包含 ~~user 的构造,就和 os.path.expanduser() 一样:

In : p = Path('~/films/prettyGirls.mp4')
In : p.expanduser()
Out: WindowsPath('C:/Users/Administrator/films/prettyGirls.mp4')


Path.home()返回一个表示当前用户家目录的新路径对象

In : p = Path('~/films/prettyGirls.mp4')
In : p.home()
Out: WindowsPath('C:/Users/Administrator')


Path.iterdir()


当路径指向一个目录时,返回该路径下的所有对象的路径(生成器):

In : for child in p3.iterdir(): print(child)
Out: D:\project\Aridea\Aridea\asgi.py
     D:\project\Aridea\Aridea\settings.py
     D:\project\Aridea\Aridea\urls.py
     D:\project\Aridea\Aridea\wsgi.py
     D:\project\Aridea\Aridea\__init__.py
     D:\project\Aridea\Aridea\__pycache__


Path.is_dir() & Path.is_file()


Path.is_dir() 判断该路径是否是文件夹 Path.is_file() 判断该路径是否是文件

print('p1:')
p1 = Path('D:/python')
print(p1.is_dir())
print(p1.is_file())

print('p2:')
p2 = Path('D:/python/1.py')
print(p2.is_dir())
print(p2.is_file())

#当路径不存在时也会返回Fasle
print('wrong path:')
print(Path('D:/NoneExistsPath').is_dir())
print(Path('D:/NoneExistsPath').is_file())


Path.stat() & Path.owner() & Path.group()


Path.stat() 获取当前文件的信息

In : p.stat()
Out: os.stat_result(st_mode=33206, st_ino=281474976758350, st_dev=130959866, st_nlink=1, st_uid=0, st_gid=0, st_size=3189, st_atime=1600237089, st_mtime=1600237088, st_ctime=1600222662)


Path.owner() 返回拥有此文件的用户名 (在windows上无效 NotImplementedError)
Path.group() 返回拥有此文件的用户组 (在windows上无效 NotImplementedError)

Path.is_absolute()


返回此路径是否为绝对路径。如果路径同时拥有驱动器符与根路径(如果风格允许)则将被认作绝对路径。

Path.joinpath(*other)


调用此方法等同于将每个 other 参数中的项目连接在一起:

In : Path('/User/augustrush').joinpath('films', 'boduoyejieyi.avi')
Out: PosixPath('/User/augustrush/films/boduoyejieyi.avi')

In : Path('/User/augustrush').joinpath('/films', 'boduoyejieyi.avi')
Out: PosixPath('/films/boduoyejieyi.avi')

In : Path('c:').joinpath('/Program Files')
Out: WindowsPath('c:/Program Files')


  • 标签云

  • 支付宝扫码支持一下

  • 微信扫码支持一下



基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建

京ICP备20007446号-1 & 豫公网安备 41100202000460号

网站地图 & RSS | Feed