29期第七周笔记

Week 7

本周学习主要内容包括文件操作、正则表达式、路径操作、shutil模块

文件操作

打开操作

open(
    file,
    mode='r',
    buffering=-1,
    encoding=None,
    errors=None,
    newline=None,
    closefd=True,
    opener=None,
)
mode:
  • mode = r:(read / readonly)
    只读,默认打开模式
    文件不存在,立即报错

  • mode = w:(write / writeonly)
    只写,不支持读取
    文件存在,文件内容将被立即清空,从头写
    小心内容将被清空!
    文件不存在,文件将被创建,从头写
    w模式为一张白纸,从头写

  • mode = a: (append)
    只写,不支持读取
    文件存在,追加写入
    文件不存在,创建文件,(从头写)对于白纸来说也就是追加写入
    a模式不管文件存在否,都从尾部写

  • mode = x:(exist)
    只写,不支持读取
    文件存在,抛异常 — 文件存在了
    文件不存在,创建新文件

以上四种主模式只能使用一个

  • mode = t:(text)
    文本模式,默认可以不写
    t模式不能单独使用,必须和rwax四种模式配合使用,不影响主模式
    EX:mode = ‘rt’ 只读不可写;mode = ‘wt’ 只写不可读
    rt才是真正的默认模式(open中mode的缺省值)

  • mode = b:(binary)
    b是binary,二进制
    b模式不能单独使用,必须和rwax四种之一配合使用,不影响主模式

  • mode = +:(plus)

  • +的意思是plus,附加的能力,必须和主模式配合使用,不影响主模式

  • r+ rt+ r+t 只读文本模式打开,补充写能力

  • w+ wt+ w+t 只写文本模式打开,补充读能力,w能力不变

文件指针

  • 文件指针指向当前字节位置

seek:
文本模式
0 seek(0) seek(0,0) seek(x) x >= 0
1 非0 不可以用,seek(0,1)原地踏步
2 非0 不可以用,seek(0,2)相对于EOF偏移0,拉回到尾部

正则表达式

  • 是文本处理极为重要的技术,用它可以对字符串按照某种规则进行检索和替换

分类

  1. BRE
    基本正则表达式,grep、sed、vi等软件支持,vim有扩展。
  2. ERE
    扩展正则表达式,egrep(grep-E)、sed-r等
  3. PCRE
    几乎所有高级语言都是PCRE的方言或者变种。python使用的SRE正则表达式引擎可以认为是PCRE的子集(模块re)

基本语法

元字符:
  • . :匹配除换行符外任意一个字符
  • [abc]:字符集合,只能表示一个字符位置,匹配所包含的任意一个字符([abc]匹配plain中的a)
  • [ ^abc ]:字符集合,只能表示一个字符位置,匹配除去集合内字符的任意一个字符
  • [a-z]:字符范围,也是个集合,表示一个字符位置,匹配所包含的任意一个字符
  • [ ^a-z]:字符范围,也是个集合,表示一个字符位置,匹配除去集合内字符的任意一个字符
  • \b:匹配单词的边界(在文本中找到单词中开头的b字符)
  • \B:不匹配单词的边界(t\B 包含t的单词但不以t结尾的字符,如write;\Bb不以b开头含b的单词,例如able)
  • \d:[0-9]匹配1位数字
  • \D:[ ^0-9]匹配1位非数字
  • \s:匹配1位空白字符,包括换行符、制表符、空格 [\f\r\n\t\v]
  • \S:匹配1位非空白字符
  • \w:匹配[a-z A-Z 0-9_],包括中文的字
  • \W:匹配\w之外的字符
转义:
  • 凡是在正则表达式中有特殊意义的符号,如果想使用它的本意,需要用 \ 转义
  • 反斜杠自身转义要使用 \
  • \r、\n还是转义后代表回车、换行
重复:
  • *:表示前面的正则表达式会重复0次或多次
  • +:表示前面的正则表达式会重复至少1次
  • ?:表示前面的正则表达式会重复0次或1次
  • {n}:重复固定的n次
  • {n}:重复至少n次
  • n}:重复n到m次
或:
  • x|y:匹配x或y
捕获:
  • (pattern):使用小括号指定一个子表达式,也叫分组;捕获后会自动分配组号从1开始;可以改变优先级
  • \数字:匹配对应的分组((very)\1匹配的是very very,但捕获的组group是very)
  • (?:pattern):如果仅仅为了改变优先级就不需要捕获分组
  • (?exp) 、(?'name’exp):命名分组捕获,但是可以通过name访问分组;python语法必须是(?Pexp)
断言:

测试字符串为 wood took foot food

零宽断言
  • (?=exp):零宽度正预测先行断言;断言exp一定在匹配右边出现,也就是说断言后面一定跟exp --> f(?=oo) f后面一定有oo出现
  • (?<=exp):零宽度正回顾后发断言;断言exp一定在匹配左边出现,也就是说断言前面一定有个exp前缀 --> (?<=f)ood、(?<=t)ook分别匹配ood、ook,ook前一定有t出现
负向宽度断言

贪婪与非贪婪

  • 默认是贪婪模式,尽量多匹配更长的字符串
  • 非贪婪很简单,再重复的符号后面加一个?问号,尽量的少匹配

引擎选项

  • 默认模式:将整个测试字符串看作一个一行的大字符串
  • 单行模式:将整个测试字符串看作一个一行的大字符串,. 可以匹配\n
  • 多行模式:可以将一行大字符串用\n分割成多行,^指的是行首,$指的是行尾

路径操作

操作模块

  • os模块常用函数 os.path模块:
from os import path

p1 = path.join('/etc','sysconfig','a/b') # -> str 拼接
p1,type(p1) #('/etc\\sysconfig\\a/b', str)

p1.split('/') #str.split 分割 ['', 'etc\\sysconfig\\a', 'b']
path.split(p1) #p1:str 一刀, rsplit,sep\ /  #('/etc\\sysconfig\\a', 'b')

Path类

from pathlib import Path
初始化
Path(),Path(''),Path('.') #(WindowsPath('.'), WindowsPath('.'), WindowsPath('.'))

Path().absolute() #绝对路径

p = Path('/etc','sysconfig','c/d')
print(p) #print和p不同,但结果都是给人看的字符串
路径拼接
  1. 操作符 /
    str / Path => Path
    Path / Path => Path
    Path / str => Path
    str / str => Error(unsupported)
Path('a') / 'b/c' # / 运算符重载
#WindowsPath('a/b/c')

'/a' / 'b/c' / Path('d','e/f') #错的
'a' / 'b/c' / Path('d','e/f') #错的

'a' /( 'b/c' / Path('d','e/f')) #正确
'/a' /( 'b/c' / Path('d','e/f')) #正确
#WindowsPath('/a/b/c/d/e/f')
  1. joinpath
    joinpath(*other)在当前Path路径上连接多个字符串返回新路径对象
p1 = ('/a' /( 'b/c' / Path('d','e/f')))
p1.parent.parent.joinpath('d1','d1/d2',Path('d3/d4','/d5'))
-------------------------------------------------------------
WindowsPath('/d5')
分解
  • parts属性,会返回目录各部分的元组
('a' /( 'b/c' / Path('d','e/f'))).parts 
#('a', 'b', 'c', 'd', 'e', 'f')

('/a' /( 'b/c' / Path('d','e/f'))).parts #最左边的 / 是根目录
#('\\', 'a', 'b', 'c', 'd', 'e', 'f')
获取路径
  • str:获取路径字符串
  • bytes:获取路径字符串的bytes
p,str(p),repr(p) 
#(WindowsPath('/etc/sysconfig/c/d'),
#'\\etc\\sysconfig\\c\\d',
#"WindowsPath('/etc/sysconfig/c/d')")

bytes(p),str(p).encode() #等价
#(b'\\etc\\sysconfig\\c\\d', b'\\etc\\sysconfig\\c\\d')
父目录
  • parent:目录的逻辑父目录
  • parents:父目录惰性可迭代对象,索引0是直接的父
p1 = WindowsPath('/a/b/c/d/e/f')
p1.parent.parent #WindowsPath('/a/b/c/d')
p1.parent.parent.parent.parent.parent.parent #WindowsPath('/')

for x in p1.parents:
    print(x)
-------------------------------
\a\b\c\d\e
\a\b\c\d
\a\b\c
\a\b
\a
\
list(Path('../a/b/c/d/e').parents) #路径系统当中,两个特殊目录
# . 引用,对当前目录自身的引用
# .. 对当前目录的父目录的引用
---------------------------------------------------------------
[WindowsPath('../a/b/c/d'),
 WindowsPath('../a/b/c'),
 WindowsPath('../a/b'),
 WindowsPath('../a'),
 WindowsPath('..'),
 WindowsPath('.')]
目录组成部分
  • name:目录的最后一个部分
  • stem:目录中最后一个部分的扩展名
  • suffix:目录最后一个部分,没有后缀
  • name = stem + suffix
  • suffixes:返回多个扩展名列表
  • with_suffix(suffix):有扩展名则替换,无则补充扩展名
  • with_name(name):替换目录最后一个部分并返回一个新的路径
全局方法
  • cwd():返回当前工作目录
  • homw():返回当前家目录
pwd #print current working path

#当前工作路径不会随着你路径的变化而变化
p1 = WindowsPath('/a/b/c/d/e/f')
p2 = Path('/data/magedu/mysql/mysql.tar.gz')
p1.cwd(),p2.cwd()
p1.home(),p2.home(),Path.home()
---------------------------------------------
(WindowsPath('C:/Users/98669/Desktop/马哥Python'),
 WindowsPath('C:/Users/98669/Desktop/马哥Python'))

(WindowsPath('C:/Users/98669'),
 WindowsPath('C:/Users/98669'),
 WindowsPath('C:/Users/98669'))
判断方法
  • exists():目录或文件是否存在(Flase – 不存在)
  • is_dir():是否是目录,目录存在返回True
  • is_file():是否是普通文件,文件存在返回True
  • is_symlink():是否是软连接
  • is_socket():是否是socket文件
  • is_block_device():是否是块设备
  • is_char_device():是否是字符设备
  • is_absolute():是否是绝对路径
  • 文件只有存在,才能知道他是什么类型
绝对路径
  • resolve()非Windows,返回一个新路径,这个新路径就是当前Path对象的绝对路径,如果是软连接则直接被解析
  • absolute()获取绝对路径
其他操作
  • iterdir():迭代当前目录,不递归
for x in p5.parent.iterdir():
    print(x)
--------------------------------
c:\temp\d1\b.txt
c:\temp\d1\d2

#p5的父目录中c:/temp下所有文件,不递归遍历,如果c:/temp有目录,判断它是否为空目录
#可以判断c:/temp所有文件的类型,dir file other
c:/temp/d1 #dir判断是否为空
c:/temp/x.txt
  • mkdir(mode=0o777, parents=False, exist_ok=False):
    parents – 是否创建父目录,True等同于mkdir -p;False时,父目录不存在,则抛出FileNotFoundError
    exist_ok – 参数,在3.5版本加入。False时,路径存在,抛出FileExistError;True时,FileExistsError被忽略
通配符(不是正则表达式)
  • glob(pattern):通配给定的模式,返回生成器对象
  • rglob(pattern):通配给定的模式,递归目录,返回生成器对象
  • ?:代表一个字符
  • *:代表任意个字符
  • [abc]或[a-z]:表示一个字符
p6 = Path('c:/temp')  
list(p6.glob('*')) #当前目录下所有文件
list(p6.glob('*.py')) #当前目录下的所有.py结尾的文件(没有即返回一个空列表)
list(p6.glob('**/*.py')) #**/ 代表当前目录下的任意次目录下的*.py
list(p6.glob('**/?.py')) # ** / 代表当前目录下的任意次目录下的?.py  (?一个  *任意个)

shutil模块

文件拷贝:由源文件读取内容,写入目标文件来完成拷贝过程,但这样会丢失stat数据信息(权限等,因为根本没有将这些信息复制过去),因为引出Python中一个库shutil(高级文件操作)

copy 复制

#1
copyfileobj(fsrc,fdst[,length])
#2
copyfile(src,dst,*,follow_symlinks=True)
#3
copymode(src,dst,*,follow_symlinks=True)
#4
copystat(src,dst,*,follow_symlinks=True)
#5
copy(src,dst,*,follow_symlinks=True)
#6
copy2
#7
copytree(src,dst,symlinks=False,ignore=None,copy_function=copy2,ignore_dangling_symlinks=False) 
  1. 文件对象的复制,fsrc和fdst是open打开的文件对象,复制内容。fdst要求可以写,length指定了表示buffer大小
  2. 复制文件内容,不含元数据,src、dst为文件的路径字符串,本质上调用的就是copyfileobj,所以不带元数据二进制内容复制
  3. 仅仅复制权限
  4. 复制元数据,stat包含权限
  5. 复制文件内容、权限和部分元数据,不包括创建时间和修改时间,本质上调用了#2、#3
  6. 比copy多了复制全部元数据,但需要平台支持,本质上调用了#2、#4
  7. 递归复制目录,默认使用copy2,也就是带更多元数据复制。src、dst必须是目录,src必须存在,dst必须不存在
    ignore = func,提供一个callable(src,name) -> ignored_names,提供一个函数,它会被调用。src是源目录,names是os.listdir(src)的结果,就是列出src中的文件名,返回值是要被过滤的文件名的set类型数据。

rm 删除

  • shutil.rmtree(path,ignore_errors=False,οnerrοr=None)
  • 递归删除,和rm -rf一样危险,慎用!!!
  • 他不是原子操作,有可能删除错误就会中断,已经删除的就删除了
  • ignore_error = True,会忽略错误,如果=False或者omitted是onerror生效
  • onerror是callable,接收函数function、path和execinfo

move 移动

  • move(src,dst,copy_function=copy2)
  • 递归移动文件、目录到目标,返回目标
  • 本身是用的就是os.rename方法
  • 如果不支持rename,如果是目录则copytree再删除源目录
  • 默认使用copy2
  • shutil还有打包功能,生成tar并压缩,支持zip、gz、bz、xz
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值