今天准备开荒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.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: 一个表示驱动器盘符或命名的字符串,如果存在
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
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')
获得文件后缀名,以及去掉后缀的文件名字
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: []
将路径绝对化,解析任何符号链接。返回新的路径对象:
In : Path().resolve()
Out: WindowsPath('D:/project/Aridea')
In : Path()
Out: PosixPath('.')
In : p.resolve()
Out: PosixPath('/home/augustrush')
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')]
改变文件的模式和权限,和 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
根据路径创建文件夹
如果给出了 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)
当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)
重命名当前文件或文件夹,如果target
所指示的文件或文件夹已存在,则覆盖原文件
在 3.8 版更改: 添加了返回值,返回新的 Path 实例。
移除此目录。此目录必须为空的。
移除此文件或符号链接。如果路径指向目录,则用 Path.rmdir() 代替。
获取当前路径
判断当前路径的文件或者文件夹是否存在
In : Path('.').exists()
Out: True
In : Path('1.py').exists()
Out:True
In : Path('2.py').exists()
Out:False
如果路径指向一个符号链接, exists() 返回此符号链接是否指向存在的文件或目录。
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')
当路径指向一个目录时,返回该路径下的所有对象的路径(生成器):
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()
判断该路径是否是文件
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()
获取当前文件的信息
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)
返回此路径是否为绝对路径。如果路径同时拥有驱动器符与根路径(如果风格允许)则将被认作绝对路径。
调用此方法等同于将每个 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构建