Python0603-路径操作

路径操作模块

3.4版本之前 os.path模块

from os import path

p = path.join('/etc', 'sysconfig', 'network')
print(1, type(p), p)  # 路径的类型,输出路径
print(2, path.exists(p))  # 路径是否存在
print(3, path.split(p))  # 路径拆分(head, tail)
print(4, path.abspath(''))  # 当前路径
p = path.join('o:/', p, 'test.txt')
print(5, path.dirname(p))  # 路径名
print(6, path.basename(p))  # 文件名
print(7, path.splitdrive(p))  # 以驱动器拆分输出路径
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 <class 'str'> /etc\sysconfig\network
2 False
3 ('/etc\\sysconfig', 'network')
4 C:\python10\code\Python06
5 o:/etc\sysconfig\network
6 test.txt
7 ('o:', '/etc\\sysconfig\\network\\test.txt')

p1 = path.abspath(__file__)
print(p1, path.basename(p1))
while p1 != path.dirname(p1):
    p1 = path.dirname(p1)
    print(p1, path.basename(p1))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\python10\code\Python06\test.py test.py
C:\python10\code\Python06 Python06
C:\python10\code code
C:\python10 python10
C:\ 

3.4版本开始 pathlib模块

  • 建议使用pathlib模块,提供Path对象操作,包括目录和文件
  • from pathlib import Path

pathlib模块-目录操作

初始化

p = Path()  # 当前目录
p = Path('a', 'b', 'c/d')  # 当前目录下的a/b/c/d
p = Path('/etc')  # 根下的etc目录
  • 路径拼接和分解

路径拼接 操作符/

  • Path对象/Path对象
  • Path对象/字符串或者字符串/Path对象

路径分解

  • parts属性,可以返回路径中的每一个部分

joinpath

  • joinpath(*other)连接多个字符串到path对象中
from pathlib import Path

p = Path()
p = p / 'a'
p1 = 'b' / p
p2 = Path('c')
p3 = p2 / p1
print(1, p3)
print(2, p3.parts)
p4 = p3.joinpath('etc', 'init.d', Path('httpd'))
print(3, p4)
~~~~~~~~~~~~~~~~~~~~
1 c\b\a
2 ('c', 'b', 'a')
3 c\b\a\etc\init.d\httpd

获取路径

  • str获取路径字符串
  • bytes获取路径字符串的bytes
from pathlib import Path

p = Path('/etc')
print(str(p), bytes(p))
~~~~~~~~~~~~~~~~~~~~~~~~~~
\etc b'\\etc'

父目录

  • parent目录的逻辑父目录
  • parents父目录序列,索引0是直接的父
  • 例如,a/b/c/d, d[0]=a/b/c,索引0是直接的父
目录根目录或当前目录a/b/c/d/
索引3210
一般通过len(p.parents)-层数,获取想得到的目录len-1len-2len-3len-4
from pathlib import Path

p = Path('a/b/c/d')
print(0, p.parent)  # d索引0的父目录是
print(1, p.parent.parent) # d索引1的父目录是
print(2, p.parent.parent.parent)  # d索引2的父目录是
print(3, p.parent.parent.parent.parent)
for x in p.parents:  # x从0开始获取父目录
    print(x)
~~~~~~~~~~~~~~~~~~~~~
1 a\b\c
2 a\b
3 a
4 .
a\b\c
a\b
a
.    
  • name、Stem、Suffix、suffixes、with-suffix(suffix)、with-name(name)
    • name目录的最后一个部分
    • suffix目录中最后一个部分的扩展名
    • stem目录最后一个部分,没有后缀
    • suffixes返回多个扩展名列表
    • with-suffix(suffix)补充扩展名到路径尾部,返回新的路径,扩展名存在则无效
    • with-name(name)替换目录最后一个部分并返回一个新的路径
from pathlib import Path

p = Path('/pythonedu/mysqlinstall/mysql.tar.gz')
print(1, p.name)
print(2, p.suffix)
print(3, p.suffixes)
print(4, p.stem)
print(5, p.with_name('mysql-5.tgz'))
p = Path('README')
print(6, p.with_suffix('.txt'))
~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 mysql.tar.gz
2 .gz
3 ['.tar', '.gz']
4 mysql.tar
5 \pythonedu\mysqlinstall\mysql-5.tgz
6 README.txt
  • cwd()返回当前工作目录
In [4]: print(p.cwd())
/home/python/steven/projects/web
  • home()返回当前家目录
In [5]: print(p.home())
/home/python
  • is_判断
    • is_dir()是否是目录目录存在返回True
    • is_file()是否是普通文件,文件存在返回True
    • is_symlink()是否是软链接
    • is_socket()是否是socket文件
    • is_block_device()是否是块设备
    • is_char_device()是否是字符设备
    • is_absolute()是否是绝对路径
In [11]: p1 = Path('/dev')

In [12]: p1
Out[12]: PosixPath('/dev')

In [13]: (p1 / 'tty').is_char_device()
Out[13]: True

In [14]: (p1 / 'tty').is_block_device()
Out[14]: False

In [15]: (p1 / 'stdout').is_symlink()
Out[15]: True

In [16]: (p1 / 'stdout').is_file()
Out[16]: False

In [17]: p2 = Path()

In [18]: p2.is_absolute()
Out[18]: False
  • resolve()返回一个新的路径,这个新路径就是当前Path对象的绝对路径,如果是软链接则直接被解析
  • absolute()也可以获取绝对路径,但是准荐使用resolve()
In [19]: Path().resolve()
Out[19]: PosixPath('/home/python/steven/projects/web')

In [4]: Path().absolute()
Out[4]: PosixPath('/home/python/steven/projects/web')
  • exists()目录或文件是否存在
In [8]: Path('/etc/test').exists()
Out[8]: False
  • rmdir()删除空目录。没有提供判断目录为空的方法
In [10]: Path('/tmp/test').rmdir()

In [11]: ll /tmp
total 0

# 如果目录有文件,会报错
OSError: [Errno 39] Directory not empty: '/tmp/test'
  • touch(mode=0o666,exist_ok=True)创建一个文件
In [29]: Path('/tmp/1.sh').touch()

In [30]: ll /tmp
total 1
-rw-rw-r-- 1 python    0 Apr 25 08:39 1.sh
  • as_uri()将路径返回成URI,例如’file:///etc/passwd’
In [31]: Path('/tmp').as_uri()
Out[31]: 'file:///tmp'
  • mkdir(mode=0o777,parents=False,exist_ok=False)
    parents,是否创建父目录,True等同于mkdir -P; False时,父目录不存在,则抛出FileNotFoundError
    exist_ok参数,在3.5版本加入。False时,路径存在,抛出FileExistsError;True时,FileExistsErrori被忽略
In [32]: Path('/tmp/test').mkdir()

In [33]: ll /tmp
total 1
drwxrwxr-x 2 python 4096 Apr 25 08:53 test/

In [37]: Path('/tmp/a/b/c/d').mkdir(parents=True)

In [39]: Path('/tmp/a/b/c/d').mkdir(parents=True, exist_ok=True)

iterdir()

  • 迭代当前路径
from pathlib import Path

p = Path()
p /= 'a/b/c/d'
print(0, p)
print(1, p.exists())  # False


p.mkdir()  # FileNotFoundError
print(2, p.exists())  # False
p.mkdir(parents=True)
p.mkdir(parents=True, exist_ok=True)
p /= 'readme.txt'
print(3, p)  # 3 a/b/c/d/readme.txt
p.parent.rmdir()  # a/b/c
p.parent.exists()  # False 'a/b/c'
p.mkdir()  # FileNotFoundError
p.mkdir(parents=True)  # 成功,'a/b/c/d/readme.txt'
# 遍历,并判断文件类型,如果是目录是否可以判断其是否为空?

from pathlib import Path

p = Path()
p /= 'a/b/c/d/readme.txt'
p.mkdir(parents=True, exist_ok=True)

for x in p.parents[len(p.parents)-1].iterdir():
    """
    p.parents[len(p.parents)-1],获取的是当前文件夹的位置, readme.txt的第4层父是. 为了获取.的位置
    p.parents[len(p.parents)-1].iterdir(),迭代生成器
    """
    print(x, end='\t')
    if x.is_dir():  # 判断是会否是文件夹
        flag = False
        for _ in x.iterdir():  # 判断里面是否有文件夹
            flag = True
            break
        # for 循环是否可以使用else子句
        print('dir', 'Not Empty' if flag else 'Empyt', sep='\t')
    elif x.is_file():  # 判断是否是文件
        print('file')
    else:
        print('other file')
~~~~~~~~~~~~~~~~~~~~
Untitled.ipynb  file
a   dir Not Empty
b   dir Empyt
Python10Training    dir Not Empty

通配符

  • glob(pattern)通配给定的模式
  • rglob(pattern)通配给定的模式,递归目录,返回一个生成器
In [4]: list(Path().glob('test*'))  # 返回当前对象下的test开头的文件
Out[4]: 
[PosixPath('test.b'),
 PosixPath('test1.py'),
 PosixPath('test.a'),
 PosixPath('test.py')]

In [5]: list(Path().glob('**/*.py'))  #递归所有目录,等同rglob
Out[5]: [PosixPath('test1.py'), PosixPath('test.py')]

In [6]: g = Path().rglob('*.py')  # 生成器

In [7]: next(g)
Out[7]: PosixPath('test1.py')

In [8]: next(g)
Out[8]: PosixPath('test.py')

匹配

  • match(pattern)
  • 模式匹配,成功返回True
Path('a/b.py').match('*.py')  # True
Path('/a/b/c.py').match('b/*.py')  # True
Path('/a/b/c.py').match('a/*.py')  # False
Path('/a/b/c.py').match('a/*/*.py')  # True
Path('/a/b/c.py').match('a/**/*.py')  # True
Path('/a/b/c.py').match('**/*.py')  # True
  • stat()相当于stat命令
  • lasts()同stat(),但如果是符号链接,则显示符号链接本身的文件信息
$ ln -s test t
$ ll
total 0
lrwxrwxrwx 1 python python 4 Apr 25 12:30 t -> test
-rw-rw-r-- 1 python python 0 Apr 25 12:30 test
In [1]: from pathlib import Path

In [2]: p = Path('test')

In [3]: p.stat()
Out[3]: os.stat_result(st_mode=33204, st_ino=917685, st_dev=2050, st_nlink=1, st_uid=502, st_gid=502, st_size=0, st_atime=1524630611, st_mtime=1524630611, st_ctime=1524630611)

In [4]: p1 = Path('t')

In [5]: p1.stat()
Out[5]: os.stat_result(st_mode=33204, st_ino=917685, st_dev=2050, st_nlink=1, st_uid=502, st_gid=502, st_size=0, st_atime=1524630611, st_mtime=1524630611, st_ctime=1524630611)

In [7]: p1.lstat()
Out[7]: os.stat_result(st_mode=41471, st_ino=917686, st_dev=2050, st_nlink=1, st_uid=502, st_gid=502, st_size=4, st_atime=1524630620, st_mtime=1524630618, st_ctime=1524630618)

文件操作

  • open(mode=’r’,buffering=-1,encoding=None,errors=None,newline=None)
  • 使用方法类似内建函数open。返回一个文件对象

3.5增加的新函数

  • read_bytes()
    • 以’rb’读取路径对应文件,并返回二进制流。看源码
  • read_text(encoding=None,errors=None)
    • 以’rt’方式读取路径对应文件,返回文本。
  • Path.write_bytes(data)
    • 以’wb’方式写入数据到路径对应文件。
  • write_text(data,encoding=None,errors=None)
    • 以’wt方式写入字符串到路径对应文件。
In [4]: p = Path('my_binary_file')

In [5]: p.write_bytes(b'Binary file contents')
Out[5]: 20

In [6]: p.read_bytes()
Out[6]: b'Binary file contents'

In [7]: p = Path('my_test_file')

In [8]: p.write_text('Text file contents')
Out[8]: 18

In [9]: p.read_text()
Out[9]: 'Text file contents'
from pathlib import Path
p = Path('test.py')
p.write_text('hello python')
print(p.read_text())
with p.open() as f:
    print(f.read(5))
~~~~~~~~~~~~~~~~~~~~~~~~~
hello python
hello
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值