路径操作:
3.4版本之前:
os.path模块:
from os import path
p = path.join('/etc', 'sysconfig', 'network')
print(type(p), p)
print(path.exists(p))
print(path.split(p))
print(path.abspath('.'))
p = path.join('o:/', p, 'test.txt')
print(path.dirname(p))
print(path.basename(p))
print(path.splitdrive(p))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3.4版本后:
使用pathlib模块,提供Path对象来操作。包括目录和文件
pathlib模块:
from pathlib import Path
目录操作:
初始化:
from pathlib import Path
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对象中
p = Path()
>>>PosixPath('.')
p = p /'a'
>>>PosixPath('a')
p1 = 'b' / p
>>> 'b/a'
p2 = Path('c')
>>> PosixPath('c')
p3 = p2 / p1
>>>'c/b/a'
print(p3.parts)
>>>('c', 'b', 'a')
p3.joinpath('etc', 'init.d', Path('httpd'))
>>>PosixPath('c/b/a/etc/init.d/httpd')
获取路径:
str 获取路径字符串
bytes 获取路径字符串的bytes
p = Path('/etc')
print(str(p), bytes(p))
>>>/etc b'/etc'
父目录:
parent 目录的逻辑父目录
parents 父目录序列,索引0是直接父
p = Path('/a/b/c/d')
print(p.parent.parent)#一个parent向上递归一次
for x in p.parents:
print(x)
>>> /a/b/c
>>> /a/b
>>> /a
>>> /
name: 目录的最后一个部分
suffix:目录中最后一个部分的扩展名
stem:目录最后一个部分,没有后缀
suffixes:返回多个扩展名列表
with_suffix(suffix):补充扩展名到尾部,扩展名存在无效
with_name(name):替换目录最后一个部分并返回一个新的路径
p = Path('/tmp/test.tar.gz')
>>> PosixPath('/tmp/test.tar.gz')
print(p.name)
>>>test.tar.gz
print(p.suffix)
>>>.gz
print(p.suffixes)
>>>['.tar', '.gz']
print('p.stem')
>>>test.tar
print(p.with_name('test2.tgz'))
>>>/tmp
p = Path('/tmp/README')
>>>PosixPath('/tmp/README')
print(p.with_suffix('.txt'))
>>>/tmp/README.txt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cwd() 返回当前工作目录
home() 返回当前家目录
is_dir() 是否是目录
is_file() 是否是普通文件
is_symlink() 是否是软链接
is_socket() 是否是socket文件
is_block_device() 是否是块设备
is_char_device() 是否是字符设备
is_absolute() 是否是绝对路径
resolve()
返回一个新的路径,这个新路径就是当前Path对象的绝对路径,
如果是软链接则直接被解析
absolute()
也可以获取绝对路径,但是推荐使用resolve()
exists()
目录或文件是否存在
rmdir()
删除空目录。没有提供判断目录为空的方法
touch(mode = 0o666, exist_ok = True)
创建一个文件
as_uri()
将路径返回为URI, 例如'file:///etc'
mkdir(mode = 0o777, parents = False, exist_ok = False)
parents 是否创建父目录,True等同于mkdir -p
False时,父目录不存在,抛出FileNotFoundError
exist_ok参数, False时,路径存在,抛出FileExistsError;True时,FileExistsError被忽略
iterdir()
迭代当前目录
p = Path()
p /= 'a/b/c/d'
>>>PosixPath('a/b/c/d')
p.exists()
>>>False
p.mkdir(parents = True)
p.exists()
>>>True 目录创建完成 就存在了
p.mkdir(parents = True)
>>>报错,目录已经存在
p.mkdir(parents = True, exist_ok = True)
>>>exist_ok = True 时,自动忽略目录存在 不报错
p /= 'readme.txt'
>>> PosixPath('a/b/c/d/readme.txt')
p.parent.rmdir()
>>>报错,目录不是空目录
p.parent.exists() False
p.mkdir()
>>>FileNotFoundError
p.mkdir(parents = True)
>>>PosixPath('a/b/c/d/readme.txt')
#遍历,并判断文件类型,如果是目录是否可以判断其是否为空
for x in p.parents[len(p.parents) -1].iterdir():
print(x, end='\t')
if x.is_dir():
flag = False
for _ in x.iterdir():
flag = True
break
print('dir', 'Not Empty' if flag else 'Empty', sep='\t')
elif x.is_file():
print('file')
else:
print('other files')
通配符:
p = Path()
glob(pattern) 通配给定的模式
rglob(pattern) 通配给定的模式,递归目录
list(p.glob('test*'))
>>>[PosixPath('test.py'), PosixPath('test')]
list(p.glob('**/*.py'))#递归所有目录等同rglob
>>>[PosixPath('test.py'),
PosixPath('a/test.py'),
PosixPath('a/1.py'),
PosixPath('a/b/yy.py'),
PosixPath('a/b/x.py')]
list(p.rglob('*.py'))
>>>[PosixPath('test.py'),
PosixPath('a/test.py'),
PosixPath('a/1.py'),
PosixPath('a/b/yy.py'),
PosixPath('a/b/x.py')]
匹配:
match(pattern)
模式匹配,成功返回True
Path('a/b.py').match('*.py') #True
Path('a/b/c.py').match('b/*.py')
Path('a/b/c.py').match('a/*.py')
Path('a/b/c.py').match('a/*/*.py')
Path('a/b/c.py').match('a/**/*.py')
Path('a/b/c.py').match('**/*.py')
文件操作:
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'方式写入字符串到路径对应文件
p = Path('content')
p.write_bytes(b'hello world')
>>>12
p.read_bytes()
>>>b'hello world'
from pathlib import Path
p = Path('d:/z/test.txt')
p.write_text('helloworld')
print(p.read_text())
with p.open() as f:
print(f.read(7))
>>>hellowo
os 模块:
os.name windows 是nt,linux是posix
os.uname() linux支持显示
sys.platform windows显示win32 linux显示linux
os.listdir('d:/z')
返回目录内容列表
>>>['open.py', 'test.txt']
创建软链接:
ln -s 目录 ——> 链接
os.stat(path, *, dir_fd = None, follow_symlinks = True)
path:路径的string、bytes 或者 fd
follow_symlinks:
True 返回文件本身信息
False 如果是软链接则显示软链接本身
win:
os.stat('d:/z/test.py')
>>>os.stat_result(st_mode=33206, st_ino=8162774324624146, st_dev=1422755607, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1509019785, st_mtime=1509019785, st_ctime=1509019785)
linux:
os.stat('test.py')
>>>os.stat_result(st_mode=33204, st_ino=150041, st_dev=2050, st_nlink=1, st_uid=501, st_gid=501, st_size=12, st_atime=1507072698, st_mtime=1507072694, st_ctime=1507072694)
os.chmod(path, mode, *, dir_fd = None, follow_symlinks = True)
os.chmod('test', 0o777)
os.chown(path, uid, gid)#可以修改文件的属主、属组,但需要足够的权限
shutil模块:
拷贝文件对象,源文件读取内容,写入目标文件中来完成拷贝过程,
这样容易丢失数据信息,因为根本没有复制过去,使用python库shutil(高级文件操作)
copy复制:
copyfileobj(fsrc, fdst[, length])
文件对象的复制,fsrc和fdst是open的文件对象,复制内容。fdst要求可写
length指定了表示buffer的大小
import shutil
with open('d:/z/test', 'r+') as f1:
f1.write('abcd\n123')
f1.flush()
with open('d:/z/test1', 'w+') as f2:
shutil.copyfileobj(f1, f2)
>>>指针直接跳到最后一个字母,不能正常复制
copymode(src, dst, *, follow_symlinks = True)
仅仅复制权限
shutil.copymode('test1', 'test')
os.stat('test1')
>>>
os.stat('test')
>>>
copystat(src, dst, *, follow_symlinks = True)
复制元数据,stat包含权限
stat test
copy(src, dst, *, follow_symlinks = True)
copyfile(src, dst, follow_symlinks = follow_symlinks)
copyfile(src, dst, follow_symlinks = follow_symlinks)
copy2比copy多了复制全部元数据,但需要平台支持
本质上调用的是:
copyfile(src, dst, follow_symlinks = follow_symlinks)
copystat(src, dst, follow_symlinks = follow_symlinks)
copytree(src, dst, symlinks = False, ignore = None, copy_function = copy2, ignore_dangling_symlinks = False)
递归复制目录。默认使用copy2,也就是带更多的元数据复制
src、dst必须是目录,src必须存在,dst必须不存在
ignore = func,提供一个callable(src, names) -> ignored_names。提供一个函数,它会被调用。src是源目录,names是os.listdir(src)的结果,
就是列出src中的文件名,返回值是要被过滤的文件名的set类型数据。
def ignore(src, names):
ig = filter(lambda x:x.startswith('a'), names)
return set(ig)
shutil.copytree('d:/z', 'd:/zz/')
rm删除:
shutil.rmtree(path, ignore_errors = False, onerror = None):
递归删除
ignore_errors为true,忽略错误。当false活着omitted时onerror生效
onerror为callable,接收函数function、path和execinfo
shutil.rmtree('d:/z')#类似rm -rf
move移动:
move(src, dst, copy_function = copy2)
递归移动文件、目录到目标,返回目标
默认使用copy2方法
os.rename('d:/t.txt', 'd:/z/x.txt')
os.rename('test3', 'd:/tmp/test33')