记录Python常用的一些标准库,以及第三方库
argpaser
add_argument说明
name="square"
- 没有
-
前缀的verbose` 是位置参数
- 没有
-a
短参数,--arg
为长参数,是可选参数,短参数与长参数可以放一起help="参数说明"
, 参数的说明type=int
,指定参数类型action="store_true"
,如果指定了参数就将True赋值给args.square,否则为False- 默认需要提供value,
--batch_size 2
store_true
,可以不传值:--is_verbose
count
,当参数出现n次就赋值为n,比如-vvv
时,就有v=3
- 默认需要提供value,
choices=[0, 1, 2]
,指定可以赋值的范围,与action="store_true"
不兼容default=0
,指定默认值,否则是None
添加参数
位置参数
positional arguments
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number", type=int)
args = parser.parse_args()
print(args.square**2)
##################用法################
python3 prog.py 4
16
可选参数
Optional arguments
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbosity", help="increase output verbosity")
args = parser.parse_args()
if args.verbosity:
print("verbosity turned on")
##################用法################
python3 prog.py --verbosity 1
verbosity turned on
默认情况,可选参数后面必须跟一个value,--verbosity any
,
如果需要只是标志类型的参数,可以设置action="store_true"
二者选其一参数
使用add_mutually_exclusive_group
可以实现两个参数只能设置其中一个的效果,比如想要设置打印日志为详细还是静默。
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
answer = args.x**args.y
if args.quiet:
print(answer)
elif args.verbose:
print("{} to the power {} equals {}".format(args.x, args.y, answer))
else:
print("{}^{} == {}".format(args.x, args.y, answer))
##################使用###############
$ python3 prog.py 4 2
4^2 == 16
$ python3 prog.py 4 2 -q
16
$ python3 prog.py 4 2 -v
4 to the power 2 equals 16
$ python3 prog.py 4 2 -vq
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
$ python3 prog.py 4 2 -v --quiet
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
最佳实践
import argparse
def paser_arg():
"""
参数解析,以及默认参数设置
:return:
"""
parser = argparse.ArgumentParser(description="说明该模块的功能")
add = parser.add_argument #将该函数赋值给add,方便后面定义参数
add("--verbose",help="是否显示详细日志内容")
return parser.parse_args()
if "__main__" == __name__:
options = paser_arg()
if options.verbose:
print("verbose print")
else:
print("no verbose print")
参考:官方argpaser
profile 性能分析
from profile import Profile
from pstats import Stats
def gcd(pair):
"""
计算最大公约数
"""
a, b = pair
low = min(a, b)
for i in range(low, 0, -1):
if a % i == 0 and b % i == 0:
return i
def main(n):
"""
被测试的函数
"""
i = 0
while i<n:
gcd((1963309, 2265973))
i+=1
p = Profile()
p.runcall(main, 100) # 函数,以及参数
# p.print_stats() # 可以直接打印报告
# 使用stats可以更加自由的定义打印的报告内容
stats = Stats(p)
stats.strip_dirs()
stats.sort_stats('cumulative')
stats.print_stats()
stats.print_callers() # 打印每个函数的调用者
203 function calls in 22.478 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 100 0.001 0.000 0.001 0.000 :0(min) 1 0.000 0.000 0.000 0.000 :0(setprofile) 1 0.001 0.001 22.477 22.477 <ipython-input-13-1e3e5803ef86>:13(main) 100 22.476 0.225 22.476 0.225 <ipython-input-13-1e3e5803ef86>:3(gcd) 1 0.000 0.000 22.478 22.478 profile:0(<function main at 0x107c720d0>) 0 0.000 0.000 profile:0(profiler) Ordered by: cumulative time Function was called by... profile:0(<function main at 0x107dffbf8>) <- profile:0(profiler)(1) 0.000 <ipython-input-21-c6df0a564b27>:13(main) <- profile:0(<function main at 0x107dffbf8>)(1) 22.548 <ipython-input-21-c6df0a564b27>:3(gcd) <- <ipython-input-21-c6df0a564b27>:13(main)(100) 22.547 :0(min) <- <ipython-input-21-c6df0a564b27>:3(gcd)(100) 22.546 :0(setprofile) <- profile:0(<function main at 0x107dffbf8>)(1) 22.548 profile:0(profiler) <-
报告说明:
- ncalls:该函数表调用的次数
- cumtime:执行该函数的所花的时间,含函数内调用其他函数的时间
- tottime:执行该函数的所花的时间,s函数内调用其他函数的时间
- percall:平均每次调用消耗的时间
pickle
The pickle
module 实现了二进制协议,用于serializing 和 de-serializing Python object structure 并保存到磁盘中,并在需要的时候读取出来,任何对象(lambda除外)都可以执行序列化操作。
Pickle模块中最常用的函数为:
保存为文件
dump(obj, file, [,protocol])
功能:将obj对象序列化存入已经打开的file中。
- obj: 想要序列化的obj对象。
- file: file对象
- protocol: 序列化使用的协议。如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。
with open('data.pickle', 'wb') as file: # 使用 highest protocol Pickle the 'data' dictionary pickle.dump(data, file, pickle.HIGHEST_PROTOCOL)
load(file)
功能:将file中的对象反序列化读出。
with open('data.pickle', 'rb') as file: # protocol版本会自动检测,不要指定 data = pickle.load(file)
因为pickle是使用二进制保存文件,因此open的读写模式,要使用‘b’
保存为string
dumps(obj [, protocol])
功能:将obj对象序列化为
string
形式,而不是存入文件中。- obj:想要序列化的obj对象。
- protocol:如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。
loads(string)
函数的功能:从string中读出序列化前的obj对象。
- string:pickle序列化后的字符串对象
import pickle # dumps li = [11,22,33] r = pickle.dumps(li) print(r) #(lp0 # I11 # aI22 # aI33 # a. # loads result = pickle.loads(r) print(result) # [11, 22, 33]
对函数、类、接口序列号
pickle 可以序列化函数,类,还有接口,但是结果数据仅仅将它们的名称编码成对应的代码对象。例如:
import math
import pickle.
pickle.dumps(math.cos)
# b'\x80\x03cmath\ncos\nq\x00.'
当数据反序列化回来的时候,会先假定所有的源数据时可用的。 模块、类和函数会自动按需导入进来。对于Python数据被不同机器上的解析器所共享的应用程序而言, 数据的保存可能会有问题,因为所有的机器都必须访问同一个源代码。
安全问题
千万不要对不信任的数据使用pickle.load()
。
pickle在加载时有一个副作用就是它会自动加载相应模块并构造实例对象。但是某个坏人如果知道pickle的工作原理,
他就可以创建一个恶意的数据导致Python执行随意指定的系统命令。因此,一定要保证pickle
只在相互之间可以认证对方的解析器的内部使用。
re
re
字符串查找
re.match
:查找字符串中是否有”从头开始”匹配的非空子串,返回match对象re.search
:查找字符串中是否有匹配的非空子串,返回第一个匹配成功的match对象re.finditer
:查找字符串中所有满足正则表达式的子串,返回全部match对象的数组import re s="she said: \"I love you\",and he replied 'me,too'" ms=re.finditer(r"(?P<quote>['\"]).*?(?P=quote)",s) for m in ms: print(m.group(0)) # "I love you" # 'me,too'
re.fullmatch
:判断是否”整个字符串”满足正则表达式re.findall
:查找所有满足正则表达式的子串,返回全部子串的数组
字符串替换
re.sub
函数调用:
text = sub(pattern,repl,string,count)
pattern
: 正则中的模式字符串repl
: 替换的字符串,sub() 函数除了接受替换字符串外,还能接受一个回调函数,(参数必须是 match 对象)string
:要被查找替换的原始字符串count
: 模式匹配后替换的最大次数,默认 0 表示替换 全部的匹配
re.subn
函数调用:`newtext, n = re.subn()` ,`n`表示发生了多少次替换
字符串分割
re.split
字符串分割,返回分割后的数组。注意括号的区别
import re
res=re.split("\|" , ' runoob|runoob|runoob.')
# [' runoob', 'runoob', 'runoob.']
res=re.split("(\|)" , ' runoob|runoob|runoob.') # 添加括号,会保留分割符
# [' runoob', '|', 'runoob', '|', 'runoob.']
pattern
为了重复利用正则表达式,将表达式编译好,保存在pattern中,用法与re的方法基本一致。
pattern = re.compile(“d”)
pattern.search(“dog”)
Match
group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0);
start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
span([group]) 方法返回 (start(group), end(group))。
时间
注意:datetime 类型是不可变对象
from datetime import datetime
# 构造datetime对象,参数代表:year,month,day,hour,minute,second
t = datetime(2019, 8, 6, 22, 30, 44)
# 获取当前时间(日期+时间点)
t = datetime.now()
print(t)
# 获取datetime对象中的日期
print(t.date())
# 获取datetime对象中的时间
print(t.time())
# 分别获取datetime对象中的属性
print(t.year)
print(t.month)
print(t.day)
# datetime对象 -> 字符串
print(t.strftime("%Y-%m-%d %H:%M:%S"))
# 字符串 -> datetime对象
print(datetime.strptime("2019-08-06", "%Y-%m-%d")) # 第2个参数表示如何解析前面的字符串
# 字符串 -> 另一格式的字符串
time_ = datetime.strptime('20200420', "%Y%m%d")
print(time_.strftime('%Y-%m-%d %H:%M:%S'))
# 修改(产生新对象,因为t不可变)
b = t.replace(minute=50, second=30)
获取当前时间
注意:datetime 下的 time 与 time 模块不同
import time
print(time.time())# 返回的UTC时间,是从1970.1.1到现在的秒数
print(time.ctime(time.time())) # 接收一个以秒为单位的时间,然后转换成本地时间的字符串表示。
print(time.strftime("%Y-%m-%d %H:%M:%S"))
from datetime import datetime
print(datetime.now())
# 1565268398.010132
# Thu Aug 8 20:46:38 2019
# 2019-08-08 20:46:38
# 2019-08-08 20:46:38.010703
时间的运算
datetime
只能相减,得到 tiemdelta
对象:datetime.timedelta(m, n)
表示相差m天n秒
tiemdelta
可以相加减,也可以与datetime
相加减得到新的 datetime
格式化字符串
%y
两位数的年份表示(00-99)%Y
四位数的年份表示(000-9999)%m
月份(01-12)%d
月内中的一天(0-31)%H
24小时制小时数(0-23)%I
12小时制小时数(01-12)%M
分钟数(00=59)%S
秒(00-59)%F
%Y-%m-%d的简写(2019-08-06)%D
%m/%d/%y的简写(08/06/19)%a
本地简化星期名称%A
本地完整星期名称%b
本地简化的月份名称%B
本地完整的月份名称%c
本地相应的日期表示和时间表示%j
年内的一天(001-366)%p
本地A.M.或P.M.的等价符%U
一年中的星期数(00-53)星期天为星期的开始%w
星期(0-6),星期天为星期的开始%W
一年中的星期数(00-53)星期一为星期的开始%x
本地相应的日期表示%X
本地相应的时间表示%z
UTC 时区偏置,格式为+HHMM或-HHMM;如果是简单时区则为空%Z
当前时区的名称%%
%号本身
tqdm
https://pypi.org/project/tqdm/#parameters
tqdm(self, iterable=None, desc=None, total=None, leave=True,file=None, ncols=None, mininterval=0.1,maxinterval=10.0, miniters=None, ascii=None, disable=False,unit='it', unit_scale=False, dynamic_ncols=False,smoothing=0.3, bar_format=None, initial=0, position=None,postfix=None, unit_divisor=1000):
- desc:progressbar的前缀
- leave : 默认True,结束后保留进度条
- ascii:默认 False,如果True,进度条将以“123456789#”显示,而不是实线
- ncols:整个消息的长度
设置提示消息
pbar = tqdm(["a", "b", "c", "d"])
for char in pbar:
time.sleep(0.25)
pbar.set_description("Processing %s" % char)
手动控制
with tqdm(total=100) as pbar:
for i in range(10):
time.sleep(0.1)
pbar.update(10) # 每次进度增加10
tqdm读取文件
from tqdm import tqdm
import codecs as cs
with tqdm(cs.open("1.txt"),desc = "status: ") as pbar:
for i in pbar:
b+=1
if b % 1000 == 0:
pbar.update(1000)
print b
多重进度条
除了 tqdm 构造函数之外,还有下面的构造函数可以用
`
python
class tqdm(xrange(args), **kwargs)
def trange(args, kwargs):
“””
A shortcut for tqdm(xrange(*args), kwargs).
On Python3+ range is used instead of xrange.
“””
class tqdm_gui(tqdm):
def tgrange(*args, **kwargs):
“””
Experimental GUI version of trange!
“””
def tnrange(*args, **kwargs):
class tqdm_notebook(tqdm):
“””
Experimental IPython/Jupyter Notebook widget using tqdm!
“””
### sys
用来处理Python运行时配置以及资源,从而可以与前当程序之外的系统环境交互,如:Python解释器。
sys.argv #命令行参数List,第一个元素是程序本身路径
sys.modules.keys() #返回所有已经导入的模块列表
sys.exc_info() #获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
sys.exit(n) #程序,正常退出时exit(0)
sys.hexversion #获取Python解释程序的版本值,16进制格式如:0x020403F0
sys.version #获取Python解释程序的版本信息
sys.maxint #最大的Int值
sys.maxunicode #最大的Unicode值
sys.modules #返回系统导入的模块字段,key是模块名,value是模块
sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform #返回操作系统平台名称
sys.stdout #标准输出
sys.stdin #标准输入
sys.stderr #错误输出
sys.exc_clear() #用来清除当前线程所出现的当前的或最近的错误信息
sys.exec_prefix #返回平台独立的python文件安装的位置
sys.byteorder #本地字节规则的指示器,big-endian平台的值是’big’,little-endian平台的值是’little’
sys.copyright #记录python版权相关的东西
sys.api_version #解释器的C的API版本
sys.version_info #获取Python解释器的版本信息
sys.getwindowsversion #获取Windows的版本
sys.getdefaultencoding #返回当前你所用的默认的字符编码格式
sys.getfilesystemencoding #返回将Unicode文件名转换成系统文件名的编码的名字
sys.setdefaultencoding(name) #用来设置当前默认的字符编码
sys.builtin_module_names #Python解释器导入的模块列表
sys.executable #Python解释程序路径
sys.stdin.readline #从标准输入读一行,sys.stdout.write(“a”) 屏幕输出a
### os
#### 文件操作
```python
os.remove() #删除文件
os.rename() #重命名文件
目录操作
os.chdir() #改变目录
os.mkdir/makedirs() #创建目录/多层目录
os.rmdir/removedirs #删除目录/多层目录
os.listdir() #列出目录下的文件名(不递归)
os.walk() #列出目录下的所有文件名(递归)
os.mkdir
与os.makedirs
的差别在于 os.makedirs
会递归地去建立目录,也就是说连同中继的目录也会一起建立,就类似于 Linux 中的 mkdir -p
.
>>> import os
>>> os.mkdir('foo/bar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: 'foo/bar'
>>> os.makedirs('foo/bar')
使用 os.mkdir
时,如果你给定的 path 参数是个多层的 path,如果某个中继的目录不存在(比如说上例中的 foo), Python 将会报错.
但如果使用 os.makedirs
则 Python 会连同中间的目录一起建立.但有一点值得注意,当 path 末端的目录已经存在的话,os.makedirs 也是会引发例外.
os.path
https://docs.python.org/3/library/os.path.html#os.path.dirname
os模块包含普遍的操作系统功能。如果你希望你的程序能够与平台无关的话,这个模块是尤为重要的。
路径操作
os.getcwd() # 取得当前工作目录
os.path.abspath(path) # 获取文件、目录的绝对路径
os.path.basename() # 文件名 ,去掉目录路径
os.path.dirname() # 目录路径 ,去掉文件名
# dirname 与 basename 组成完整的文件路径(绝对、相对路径都可以)
os.path.join() # 将分离的各部分组合成一个路径名
os.path.split(path) # 返回(dirname(),basename())元组
# 将路径名*path*分割为(head, tail) , *tail* 路径名的最后部分,绝对不包含分隔符(/) *head* 是 tail 之前的路径。如果*path* 以(/) 结尾, 那么*tail* 为空
os.path.splitdrive(path)# 返回(盘符、远程地址,路径)元组
os.path.splitext(path) # 返回(剩余部分,扩展名)元组
os.path.commonpath(paths) #返回公共的父节点路径(有效路径)
os.path.commonprefix(list) #返回公共的路径前缀(字符串匹配,不一定是有效路径)
# commonprefix(['/usr/lib', '/usr/local/lib'])
# '/usr/l'
# commonpath(['/usr/lib', '/usr/local/lib'])
# '/usr'
os.path.realpath(path) #返回真实路径,消除符号链接,类似于abspath
os.path.relpath(path, start=os.curdir) #返回相对于指定的start的相对路径,默认是当前目录
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False。
os.path.isabs(path) 如果path是绝对路径,返回True。
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False。
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False。
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略。
os.path.normcase(path) 在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠。
os.path.normpath(path) 规范化路径。
os.path.expanduser(path)# 将路径中的~转义为真实的home目录地址,否则不做变化
os.path.expandvars(path)# 将路径中的环境变量转义为真实的值,否则不做变化
os.path.normcase(path)
返回大小写正常化后的路径名。
对于 Mac、Unix,该操作没有效果(他们对a.txt
,A.txt
视为同一名称)
对于不区分大小写的文件系统,会将路径转为小写;
对于 window,前向斜杆\
会转为后向斜杆/
文件判断
os.path.getatime\ctime\mtime # 分别返回最近访问、创建、修改时间
os.path.isfile(path) # 是否为文件
os.path.isdir(path) # 是否为目录
os.path.getsize() # 返回文件大小
os.path.exists(path) # 是否存在
os.path.isabs() # 是否为绝对路径
os.path.islink() # 判断是否为连接符号,获取真实路径请看上面的realpath函数
os.path.samefile(path1, path2) # 是否是同一个文件
os.path.sameopenfile(fp1, fp2) # 是否指向同一个文件
configparser
import configparser
import os
#实例化ConfigParser
cf = configparser.ConfigParser()
#获取当前的绝对路径
current_path = os.path.abspath(__file__)
#当前文件的目录
now_cig = os.path.dirname(current_path)
#拼接配置文件路径
con_cig = os.path.join(now_cig + "/config/config.ini")
#读取配置文件
cf.read(con_cig)
#打印配置文件里面section名为"people"里面的options
print(cf.options(section='people'))
#打印配置文件里面section里面的某个potions的value
print(cf.get('people','name'))
#加添section
cf.add_section('cc')
#设置指定section的key=value
cf.set('cc','aa','bb')
print(cf.options(section='cc'))
shutil
https://docs.python.org/3/library/shutil.html#shutil.disk_usage
从文件对象拷贝
copyfileobj(fsrc, fdst[, length])
# with 可以同时 支持 多个上下文管理器
with open("./1.txt",encoding='utf8') as f1, open('./2,txt','w',encoding='utf8') as f2:
su.copyfileobj(f1,f2)
文件操作
复制
copyfile(src, dst, *, follow_symlinks=True)
从 src复制的文件内容到 dst 文件中,只复制内容,不包含元数据
dst 必须是目标文件名,而不是目录
copy(src, dst, *, follow_symlinks=True*)
复制文件数据、权限数据;其他的元数据(创建时间、修改时间)没有保留
dst允许是目录,或者文件名
copy2(src, dst, *, follow_symlinks=True)
与 copy 一样,除了会尽量保存文件的元数据
移动(文件/目录)
move(src, dst, copy_function=copy2)
将文件或者目录复制到 dst
目录操作
复制
copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False)
将递归地将整个目录文件复制到 dst,dst 必须不存在
例子:跳过指定的文件
from shutil import copytree, ignore_patterns
copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
利用 ignore 进行日志记录功能
from shutil import copytree
import logging
def _logpath(path, names):
logging.info('Working in %s', path)
return [] # nothing will be ignored
copytree(source, destination, ignore=_logpath)
移动
参考 move
删除
rmtree(path, ignore_errors=False, onerror=None)
删除整个目录,path 必须指向目录 (不可以是指向目录的符号链接).
例子:处理只读的文件,尝试删除
import os, stat
import shutil
def remove_readonly(func, path, _):
"清除 readonly bit 并重新尝试删除"
os.chmod(path, stat.S_IWRITE)
func(path)
shutil.rmtree(directory, onerror=remove_readonly)
ignore_patterns
This factory function creates a function that can be used as a callable for copytree()
’s ignore argument, ignoring files and directories that match one of the glob-style patternsprovided.
文件状态操作
复制文件权限
copymode(src, dst, *, follow_symlinks=True)
从 src 复制 permission bits 到 dst。文件内容、拥有者、组都不受影响
复制文件状态
copystat(src, dst, *, follow_symlinks=True)
从 src 复制 permission bits、 last access time、last modification time、 flags 到 dst. 在 linux 中,还会尝试复制 “extended attributes”
文件内容、拥有者、组都不受影响
chown
chown(path, user=None, group=None)
修改 path 的用户或者组
其他
磁盘使用情况
disk_usage(path)
返回磁盘的使用情况统计结果元组:total, used, free, 单位是 bytes.
which
which(cmd, mode=os.F_OK | os.X_OK, path=None)
查看命令的执行程序名称
shutil.which("python")
# '/Users/jizhongxian/anaconda3/bin/python'
Archiving operations(压缩包操作)
用到再看
https://docs.python.org/3/library/shutil.html#archiving-operations
glob
glob 规则:http://www.man7.org/linux/man-pages/man7/glob.7.html
最常用的通配符是 *、?、[]
通配符 | 描述 | 例子 | 匹配 | 不匹配 |
---|---|---|---|---|
* | 匹配任意数量的字符包括空字符 | Law* | Law, Laws, or Lawyer | |
*Law* | Law, GrokLaw, or Lawyer. | |||
? | 匹配任意一个字符 | ?at | Cat, cat, Bat or bat | at |
[abc] | 匹配任意一个包含的字符 | [CB]at | Cat or Bat | cat or bat |
[a-z] | 匹配任意一个给定范围的字符 | Letter[0-9] | Letter0, Letter1 etc. | Letters or Letter |
** | 匹配任意的目录(包括当前目录) | */\.js | ss.js, a/hh.js, a/b/c.js |
在Linux和POSIX系统中[…]的扩展
通配符 | 描述 | 例子 | 匹配 | 不匹配 |
---|---|---|---|---|
[!abc] | 不匹配任意一个包含的字符 | [!C]at | Bat, bat, or cat | Cat |
[!a-z] | 不匹配任意一个给定范围的字符 | Letter[!3-5] | Letter1, Letter2 etc. | Letter3, Letter4 or Letter5 |
与正则的比较:
Glob的通配符 | 等价正则的表达式 |
---|---|
? | . |
* | .* |
注意事项
- Glob尝试匹配整个字符串,而不是片段。
S*.DOC
将匹配S.DOC和SA.DOC,但不匹配POST.DOC或SURREY.DOCKS,正则只匹配子串除非使用^
和$
。所以S*.DOC
的等价正则是^S.*\.DOC$
。 - 路径分隔符(unix的/,windows的\)不会被
? *
匹配。如果要匹配,需要用**
匹配任意层级的目录(包括当前目录)**/*.js ==> a/b/c.js
[^...]
是无效的.
开头的文件被 glob 视为特殊的文件,*
匹配不到他,需要显式处理>>> import glob >>> glob.glob('*.gif') ['card.gif'] >>> glob.glob('.c*') #显式地指定. ['.card.gif']
glob
glob.glob(pathname, *, recursive=False)
返回符合 pathname 模式的路径列表,recursive会递归地查找
import glob
glob.glob('./[0-9].*')
# ['./1.gif', './2.txt']
glob.glob('*.gif')
# ['1.gif', 'card.gif']
glob.glob('?.gif')
# ['1.gif']
glob.glob('**/*.txt', recursive=True)
# ['2.txt', 'sub/3.txt']
glob.glob('./**/', recursive=True)
# ['./', './sub/']
iglob
glob.iglob(pathname, *, recursive=False)
与 glob 作用相同,只不过返回的一个迭代器
escape
glob.escape(pathname)
转义所有的字符('?'
, '*'
and '['
)。
比如escape('//?/c:/Quo vadis?.txt')
返回 '//?/c:/Quovadis[?].txt'
.
fnmatch
Pattern | Meaning |
---|---|
* |
matches everything |
? |
matches any single character |
[seq] |
matches any character in seq |
[!seq] |
matches any character not in seq |
('/'
on Unix) .
开头的文件,不是特殊文件
fnmatch
fnmatch.fnmatch(filename, pattern)
测试 filename 是否匹配 pattern 字符串, 参数都是用 os.path.normcase()
规范过了。 fnmatchcase()
用于 大小写敏感的比较, 不论那是否是该操作系统的标准
import fnmatch
import os
for file in os.listdir('.'):
if fnmatch.fnmatch(file, '*.txt'):
print(file)
fnmatchcase
fnmatch.fnmatchcase(filename, pattern)
大小写敏感的比较,函数中不使用os.path.normcase()
.
filter
fnmatch.filter(names, pattern)
返回列表 names 中符合 pattern 的子列表,等价于[n for n in namesif fnmatch(n, pattern)]
, 但内部更进行了高效地实现。
translate
fnmatch.translate(pattern)
将 shell-风格的 pattern 转为正则表达式re.match()
.import fnmatch, re regex = fnmatch.translate('*.txt') print(regex) # '(?s:.*\\.txt)\\Z' reobj = re.compile(regex) reobj.match('foobar.txt') # <re.Match object; span=(0, 10), match='foobar.txt'>