当前位置:首页 > Python教程 > python技巧

我的python学习之路-基础4

本节内容:

  1. 递归函数
  2. 内置函数
  3. 模块
  4. 正则表达式

 

 

一、 递归函数

定义:自己调用自己的函数,就是递归函数

  递:去     归:回      一去一回是递归

1、基本写法

            def
             digui(n):
    
            print(n,"<----start---->")
    if n>0:
        digui(n-1)
    print(n,"<-----end----->")
    
digui(5)

代码解析:

去的过程:

n = 5 print(5,"<--start-->") if 5 > 0 digui(n - 1) => digui(4) 代码阻塞在第13行

n = 4 print(4,"<--start-->") if 4 > 0 digui(n - 1) => digui(3) 代码阻塞在第13行

n = 3 print(3,"<--start-->") if 3 > 0 digui(n - 1) => digui(2) 代码阻塞在第13行
n = 2 print(2,"<--start-->") if 2 > 0 digui(n - 1) => digui(11 代码阻塞在第13行
n = 1 print(1,"<--start-->") if 1 > 0 digui(n - 1) => digui(0) 代码阻塞在第13行
n = 0 print(0,"<--start-->") if 0 > 0 条件不满足 print(0,"<--end-->")

[如果最后一层函数执行结束,将触发归的过程,把没执行完的代码执行结束.]

归的过程:
n = 1 走到上一次代码阻塞13行的位置,往下走 print(1,"<--end-->")
n = 2 走到上一次代码阻塞13行的位置,往下走 print(2,"<--end-->")
n = 3 走到上一次代码阻塞13行的位置,往下走 print(3,"<--end-->")
n = 4 走到上一次代码阻塞13行的位置,往下走 print(4,"<--end-->")
n = 5 走到上一次代码阻塞13行的位置,往下走 print(5,"<--end-->")

栈帧空间:函数调用时,每次调用都会在内存中独立开辟一个空间,叫做栈帧空间,
是独立的副本,空间和空间之间数据不共享

总结:
(1)递归就是不停的开辟和不停的释放栈帧空间的过程,整合在一起时递归
(2)触发递归函数归的过程有两种:
(1) 递归在最后一层栈帧空间代码全部执行结束的时候,触发归的过程
(2) 遇到函数中的return,回到上一层栈帧空间从阻塞处继续向下执行
(3) 在写递归时,务必给与递归跳出的条件,不能无限递归下去,否则内存溢出,蓝屏死机
(4) 如果递归的层次太深,不建议使用递归;(官方说法1000层,因个人电脑而已

 2、练习题

1.使用递归完成任意数n的阶乘

            def
             jiecheng(n):
    
            if 0<= n <=1:
        return 1
    return n * jiecheng(n-1)

代码解析

技术分享图片 技术分享图片
                 1
                ‘‘‘
                 2
                去的过程:

                 3
                n = 5  return n * jiecheng(n-1)    => return 5 * jiecheng(4)

                 4
                n = 4  return n * jiecheng(n-1) => return 4 * jiecheng(3)

                 5
                n = 3  return n * jiecheng(n-1) => return 3 * jiecheng(2)

                 6
                n = 2  return n * jiecheng(n-1) => return 2 * jiecheng(1)

                 7
                n = 1  return 1

                 8
                 9
                归的过程:

                10
                n = 2  return n * jiecheng(n-1) => return 2 * 1

                11
                n = 3  return n * jiecheng(n-1) => return 3 * 2 * 1

                12
                n = 4  return n * jiecheng(n-1) => return 4 * 3 * 2 * 1

                13
                n = 5  return n * jiecheng(n-1) => return 5 * 4 * 3 * 2 * 1

                14
                所有代码执行结束 : 返回 return 5 * 4 * 3 * 2 * 1 => 120

                15
                ‘‘‘
            
View Code

 

2.使用尾递归完成任意数n的阶乘

尾递归: 自己调用自己,且非表达式
特点 : 计算的结果在参数中运算;

            def
             jiecheng(n,endval):
    
            if n <= 1:
        return endval
    return jiecheng(n-1,n*endval)
print(jiecheng(5,1))

尾递归的特点:最后一层函数调用结束后的返回值,就是最顶级函数调用的结果,
所以我们的思维逻辑只考虑递去的过程即可,归的思维逻辑可以不考虑了;
需要在写递归时,在参数运算时动脑筋;

代码解析:

技术分享图片 技术分享图片
                 1
                """
                 2
                代码去的过程:

                 3
                n = 5 , endval = 1 if n <= 1: 条件不成立 return jiecheng(5-1,5*1) => jiecheng(4,5*1)

                 4
                n = 4 , endval = 5*1 if n <= 1: 条件不成立 return jiecheng(4-1,4*5*1) => jiecheng(3,4*5*1)

                 5
                n = 3 , endval = 4*5*1 if n <= 1: 条件不成立 return jiecheng(3-1,3*4*5*1) => jiecheng(2,3*4*5*1)

                 6
                n = 2 , endval = 3*4*5*1 if n <= 1: 条件不成立 return jiecheng(2-1,2*3*4*5*1) => jiecheng(1,2*3*4*5*1)

                 7
                n = 1 , endval = 2*3*4*5*1 if n <= 1: 条件成立 return endval [2*3*4*5*1]

                 8
                 9
                递归归的过程:

                10
                最后一层结果就是函数顶级调用的结果.一深直入;

                11
                12
                """
            
View Code

尾递归在一些特别的解释器中,每次调用函数时,都只在内存中开辟一个栈帧空间,

后者替换前者,只要最后一层空间有数据返回,直接结束.
但是目前cpython解释器不支持,仍然是有去有回;

优化代码

            #
             优化代码1
            def jiecheng(n,endval=1):
    if n <= 1:
        return endval
    return jiecheng(n-1,n*endval)
print(jiecheng(5,1))

# 优化代码2def outer(n):
    def jiecheng(n,endval=1):
        if n <= 1:
            return endval
        return jiecheng(n-1,n*endval)
    return jiecheng(5,1)

print(outer(5))

3.使用递归完成斐波那契数列

            def
             feb(n):
    
            if n == 1 or n == 2:
        return 1
    #      寻找上一个值 + 寻找上上个值return feb(n - 1) + feb(n - 2)
print(feb(5))

 

 

 二、内置函数

1、abs    绝对值函数

res = abs(-1)
print(res)

2、round 四舍五入

(n.5 n为偶数则舍去 n.5 n为奇数,则进一!)

res = round(3.69)#4
res = round(3.5)#4
res = round(4.5) #4
res = round(4.51)#5

3、sum    计算一个序列得和

lst =[1,2,3,4]
res = sum(lst)

4、max  min 获取一个序列里边的最大值 最小值

lst = [100,200,20,-3]
# max 获取一个序列里边的最大值
res = max(lst)
# min 获取一个序列里边的最小值
res = min(lst)
print(res

其他方法

lst = sorted(lst)
maxval = lst[-1]
minval = lst[0]
print(maxval,minval)

max与min的高阶用法与sorted相同
return 最终返回的数据和传入到自定义函数中的数据是一致的

container = {"何子豪":100,"李雅琪":200,"王雨涵":300}
def func(n):
    print(container[n])
    # 返回的是年龄,按照年龄找到最大值最小值return container[n]

res = max(container,key=func)
res = min(container,key=func)
print(res)

5、pow    计算某个数值的x次方

            #
             pow    计算某个数值的x次方
res = pow(2,3)
# 前2个参数的结果和第三个参数取余
res = pow(2,3,5)
print(res)

6、进制转化函数

            #
             bin    将10进制数据转化为二进制
res = bin(255)
print(res)

# oct    将10进制数据转化为八进制
res = oct(8)
print(res)

# hex    将10进制数据转化为16进制
res = hex(255)
print(res)

7、字符和ASCII转化函数

            #
             chr    将ASCII编码转换为字符
res = chr(97)
print(res)
# ord    将字符转换为ASCII编码
res = ord("a")
print(res)

8、字符串转换成Python代码函数

            #
             eval   将字符串当作python代码执行 (慎用)
strvar = "print(123434343434)"
strvar = "a=100"# print(strvar)
# eval(strvar) error# exec   将字符串当作python代码执行(功能更强大) (慎用)
strvar = "a=100"
strvar = """
for i in range(50):
    print(i)
"""exec(strvar)

9、repr   不转义字符输出字符串 [等价于元字符串]

pathvar = "D:notepadd++t"print(repr(pathvar))

10、hash   生成哈希值

res1 = hash("a")
res2 = hash("a")
print(res1,res2)

 

 三、模块

 1、数学模块 math

技术分享图片 技术分享图片
                 1
                import
                 math

                 2
                #
                ceil()  向上取整操作 (对比内置round) ***
                 3 res = math.ceil(3.1)
 4 res = math.ceil(-3.5)
 5print(res)
 6 7#floor() 向下取整操作 (对比内置round) *** 8 res = math.floor(4.199)
 9 res = math.floor(-4.199)
10print(res)
1112#pow()  计算一个数值的N次方(结果为浮点数) (对比内置pow) ***13 res = math.pow(2,3)
14# math中的pow方法没有三个参数,只有2个;15# res = math.pow(2,3,2) error16print(res)
1718#sqrt() 开平方运算(结果浮点数) ***19 res = math.sqrt(9)
20print(res) # 3.02122#fabs() 计算一个数值的绝对值 (结果浮点数) (对比内置abs)23 res = math.fabs(-999)
24print(res)
2526#modf() 将一个数值拆分为整数和小数两部分组成元组27 res = math.modf(3.567)
28print(res)
2930#copysign()  将参数第二个数值的正负号拷贝给第一个 (返回一个小数)31 res = math.copysign(-18,-19)
32print(res)
3334#fsum() 将一个容器数据中的数据进行求和运算 (结果浮点数)(对比内置sum)35 lst = [1,2,3,4]
36print(math.fsum(lst))
3738#圆周率常数 pi ***39 res = math.pi
40print(res)
View Code

2、随机模块 random

 1、random() 获取随机0-1之间的小数(左闭右开)

            import
             re
res = random.random()
print(res)

2、randrange() 随机获取指定范围内的整数(包含开始值,不包含结束值,间隔值)

            #
             一个参数
res = random.randrange(5)
print(res)

# 二个参数
res = random.randrange(1,7)
print(res)

# 三个参数
res = random.randrange(1,10,3) # 1 4 7 print(res)

3、randint()   随机产生指定范围内的随机整数 (了解)

res = random.randint(1,4) # 留头留尾print(res)

4、uniform() 获取指定范围内的随机小数(左闭右开) 

res = random.uniform(2,4) # 2 <= x < 4
res = random.uniform(4,2) # 2 < x <= 4print(res)

5、choice()  随机获取序列中的值(多选一)

lst = ["耿择时","孙翔宇","家营和","张银"]
res = random.choice(lst)
print(res

6、sample()  随机获取序列中的值(多选多) [返回列表]

lst = ["耿择时","孙翔宇","家营和","张银"]
res = random.sample(lst,2)
print(res) # 返回列表

7、shuffle() 随机打乱序列中的值(直接打乱原序列)

lst = [1,2,3,4,45,5,6]
random.shuffle(lst)
print(lst) #[3, 5, 4, 6, 45, 2, 1]

8、验证码功能

技术分享图片 技术分享图片
                 1
                def
                 yanzhengma():

                 2     strvar = "" 3for i in range(4):
 4# 元素中包含数字 5         num = str(random.randrange(10))
 6# 元素中含有小写字母 7         s_c = chr(random.randrange(97,123))
 8# 元素中含有大写字母 9         b_c = chr(random.randrange(65,91))
10# 把可能的元素扔到列表中,随机抽11         lst = [num,s_c,b_c]
12# 把随机抽取的4次内容都叠加到字符串strvar中13         strvar += random.choice(lst)
14return strvar
View Code

3、 pickle 序列化模块

序列化:   把不能够直接存储的在文件中的数据变得可存储

反序列化 :把存储的数据拿出来恢复成原来的数据类型

 需要配合文件操作 使用 dump 和 load

不需要配合文件操作 使用 dumps 和 loads

1、dump  把对象序列化后写入到file-like Object(即文件对象)

lst = [1,12,3,4]
with open("ceshi1.txt",mode="wb") as fp:
    pickle.dump(lst,fp)

2、load  把file-like Object(即文件对象)中的内容拿出来,反序列化成原来数据

with open("ceshi1.txt",mode="rb") as fp:
    res = pickle.load(fp)
print(res,type(res))

3、dumps 把任意对象序列化成一个bytes

            #
             序列化函数
            def
             func():
    
            print("我是func函数 ... ")

res = pickle.dumps(func)
print(res)

4、loads 把任意bytes反序列化成原来数据

            #
             反序列化函数字节流
func = pickle.loads(res)
func()

5、使用dumps 和 loads 将数据存储到文件中

with open("ceshi1.txt",mode="wb") as fp:
    res1 = pickle.dumps(it)
    fp.write(res1)

with open("ceshi1.txt",mode="rb") as fp:
    res = fp.read()
    it = pickle.loads(res)
print(next(it))
print(next(it))

4、json 模块

所有编程语言都能够识别的数据格式叫做json,是字符串
能够转换的数据格式 : int float bool str list tuple dict None

json : 一般用来做数据的传输,序列化成字符串
pickle : 一般用来做数据的存储,序列化成字节流

1.json 的用法

(1)json中的 dumps 和  loads 
dic = {"name":"于盛林","age":25,"sex":"男性","family":["老于","小鱼","小小鱼"]}

# 序列化
# ensure_ascii=False 显示中文 , sort_keys=False 对字典的键进行排序
res = json.dumps(dic,ensure_ascii=False,sort_keys=True) 
print(res , type(res))

# 反序列化
dic = json.loads(res)
print(dic, type(dic))
(2)json中的  dump 和 load
with open("ceshi2.txt",mode="w",encoding="utf-8") as fp:
    json.dump(dic,fp,ensure_ascii=False)

with open("ceshi2.txt",mode="r",encoding="utf-8") as fp:
    dic = json.load(fp)
print(dic,type(dic))

2.json 和 pickle 之间的区别

(1)json

json可以连续dump , 但是不能连续的load
load是一次性把所有数据拿出来反序列化成原来的数据类型

技术分享图片 技术分享图片
                 1
                """
                 2
                dic1 = {"a":1,"b":2}

                 3
                dic2 = {"c":3,"d":4}

                 4
                # 连续dump

                 5
                with open("ceshi3.txt",mode="w",encoding="utf-8") as fp:

                 6
                    json.dump(dic1,fp)

                 7
                    fp.write("n")

                 8
                    json.dump(dic2,fp)

                 9
                    fp.write("n")

                10
                11
                # 连续load error 

                12
                """
                13 with open("ceshi3.txt",mode="r",encoding="utf-8") as fp:
14    json.load(fp)
15    json.load(fp)
16"""17# 解决
18with open("ceshi3.txt",mode="r",encoding="utf-8") as fp:
19    for i in fp:
20        dic = json.loads(i)
21        print(dic, type(dic))
View Code
(2)pickle

pickle可以连续dump , 也能连续的load

技术分享图片 技术分享图片
                 1
                import
                 pickle

                 2 dic1 = {"a":1,"b":2}
 3 dic2 = {"c":3,"d":4}
 4# 连续dump 5 with open("ceshi4.txt",mode="wb") as fp:
 6    pickle.dump(dic1,fp)
 7    pickle.dump(dic2,fp)
 8 9# 连续load10 with open("ceshi4.txt",mode="rb") as fp:
11     dic1 = pickle.load(fp)
12print(dic1 , type(dic1))
13     dic2 = pickle.load(fp)
14print(dic2 , type(dic2))
View Code

一次性把所有数据全部拿取出来

with open("ceshi4.txt",mode="rb") as fp:
    try:
        while True:            
            dic = pickle.load(fp)
            print(dic , type(dic))
    except:
        pass
(3)json 和 pickle 两个模块的区别

(1)json序列化之后的数据类型是str,所有编程语言都识别,

   但是仅限于(int float bool)(str list tuple dict None)

   json不能连续load,只能一次性拿出所有数据

(2)pickle序列化之后的数据类型是bytes,

   所有数据类型都可转化,但仅限于python之间的存储传输.

   pickle可以连续load,多套数据放到同一个文件中

5、time 时间模块

技术分享图片 技术分享图片
                 1
                import
                 time

                 2
                #
                time()          获取本地时间戳
                 3 res = time.time()
 4print(res)
 5 6# localtime  =>  mktime  =>  ctime 7# 返回元组   =>  返回时间戳 =>  时间字符串 8# 1.localtime()     获取本地时间元组         (参数是时间戳,默认当前) 9 res = time.localtime()
10print(res)
11# 指定时间戳12 ttp = time.localtime(1600000000)
13print(ttp)
1415# 2.mktime()        通过时间元组获取时间戳    (参数是时间元组)16 ttp = (2020,12,9,11,5,59,0,0,0)
17 res = time.mktime(ttp)
18print(res)
1920# 3.ctime()         获取本地时间字符串(参数是时间戳,默认当前)21 res = time.ctime()
22print(res)
2324# 指定时间戳25 res = time.ctime(1607483245)
26print(res)
272829#asctime()       通过时间元组获取时间字符串(参数是时间元组) (了解)30"""不能自动识别周几"""31 ttp = (2020,12,9,11,5,59,0,0,0)
32 res = time.asctime(ttp)
33print(res)
3435# 解决办法:36 res = time.mktime(ttp) # 变成时间戳37 time_str = time.ctime(res) # 变成时间字符串;38print(time_str)
3940#sleep()         程序睡眠等待41# time.sleep(2)42# print("我睡醒了")43444546# 注意:=> strftime 时间元组 => 时间字符串 47# 4.strftime()      格式化时间字符串(格式化字符串,时间元组)48"""linux支持中文显示,windows默认不支持"""49 res = time.strftime("你好 :%Y-%m-%d %H:%M:%S ")
50print(res)
5152# 指定时间元组格式化字符串;53 ttp = (2021,12,9,11,5,59,0,0,0)
54 res = time.strftime("你好 :%Y-%m-%d %H:%M:%S " , ttp)
55print(res)
5657# 注意:=> strptime 时间字符串 => 时间元组58# 5.strptime()      将时间字符串通过指定格式提取到时间元组中(时间字符串,格式化字符串) 59"""字符串必须严丝合缝,不能随便加空格;否则报错"""60 strvar1="著名的NBA球星霍华德的生日是2020年12月8号,在家里的泳池中下午15点30分40秒开派对"61 strvar2="著名的NBA球星霍华德的生日是%Y年%m月%d号,在家里的泳池中下午%H点%M分%S秒开派对"62 res = time.strptime(strvar1,strvar2)
63print(res)
646566#perf_counter()  用于计算程序运行的时间 (了解)67 startime = time.time()
68# startime = time.perf_counter()69for i in range(10000000):
70pass71 endtime = time.time()
72# endtime = time.perf_counter()73print("用的时间是{}".format(endtime-startime))
View Code

6、压缩模块zipfile (后缀为zip)

技术分享图片 技术分享图片
                 1
                import
                 zipfile

                 2
                 3
                 4
                #
                 1.创建压缩包
                 5
                #
                 (1)打开压缩包
                 6 zf = zipfile.ZipFile("ceshi100.zip","w",zipfile.ZIP_DEFLATED)
 7# zf.write(路径,别名) 8# (2)写入文件 9 zf.write("/bin/chmod","chmod")
10 zf.write("/bin/cat","cat")
11 zf.write("/bin/chown","tmp/chown")
12# (3)关闭文件13zf.close()
141516# 2.解压文件17 zf = zipfile.ZipFile("ceshi100.zip","r")
18# 解压所有 extractall(路径)19# zf.extractall("ceshi100")20 zf.extract("cat","ceshi200")
21zf.close()
222324# 3.查看压缩包 支持with语法 (自动实现close操作,不需要手动)25 with zipfile.ZipFile("ceshi100.zip","r") as zf:
26     lst = zf.namelist()
27print(lst)
282930# 4.追加文件31 with zipfile.ZipFile("ceshi100.zip","a",zipfile.ZIP_DEFLATED) as zf:
32     zf.write("/bin/ln","ln")
View Code
技术分享图片 技术分享图片
                 1
                def
                 progress(percent):

                 2
                #
                 如果传入的比例超过100% ,强制等于100%;
                 3
                if percent > 1:
 4         percent = 1
 5     strvar = int(50 * percent) * "#" 6print("r[%-50s] %d%%" % (strvar , percent * 100),end="")
 7 8 recv_data = 0
 9 total = 1024
10while recv_data < total:
11# 延迟0.1秒12     time.sleep(0.1)
13     recv_data += 100
14# 比例 = 接受数据的大小  /  总大小 15     percent = recv_data / total
16# 把比例扔给progress,显示实际的进度条效果;17     progress(percent)
进度条演示

7、OS模块  对系统进行操作

技术分享图片 技术分享图片
                 1
                import
                 os

                 2
                #
                system()  在python中执行系统命令
                 3
                #
                 os.system("touch 1.txt")
                 4
                #
                 os.system("ipconfig")
                 5
                #
                 os.system("ifconfig")
                 6
                 7
                #
                popen()   执行系统命令返回对象,通过read方法读出字符串
                 8
                #
                 obj = os.popen("ifconfig")
                 9
                #
                 res = obj.read()
                10
                #
                 print(res)
                11
                12
                #
                listdir() 获取指定文件夹中所有内容的名称列表
                13 lst = os.listdir(".")
14print(lst)
1516#getcwd()  获取当前文件所在的默认路径17# 路径18 res = os.getcwd()
19print(res)
2021# 路径 + 文件22print(__file__)
2324#chdir()   修改当前文件工作的默认路径25 os.chdir("/home/wangwen/mysoft/")
26# os.system("mkdir ceshi100")27 os.system("rm -rf ceshi100")
2829#environ   获取或修改环境变量30print(os.environ)
31print(os.environ["PATH"])
32 os.environ["PATH"] += ":/home/wangwen/mysoft"33 os.system("wangwen")
343536#--os 模块属性37#name 获取系统标识   linux,mac ->posix      windows -> nt38print(os.name)
3940#sep 获取路径分割符号  linux,mac -> /       window-> 41 res = "wangwen"+ os.sep + "notepad"42print(repr(res))
4344#linesep 获取系统的换行符号  linux,mac -> n    window->rn 或 n45print(repr(os.linesep))
os模块操作
技术分享图片 技术分享图片
                 1
                import
                 os

                 2 os.chdir("/home/wangwen/mysoft/")
 3 4os.mknod   创建文件 (windows目前版本还存在兼容性问题,等待版本迭代;)
 5 os.mknod("lianxi.py")
 6os.remove  删除文件
 7 os.remove("lianxi.py")
 8os.mkdir   创建目录(文件夹)
 9 os.mkdir("abc_ww")
10os.rmdir   删除目录(文件夹)
11 os.rmdir("abc_ww")
12os.rename  对文件,目录重命名
13 os.rename("lianxi1","lianxi2")
14os.makedirs   递归创建文件夹
15 os.makedirs("a/b/c/d/e/f/g")
16os.removedirs 递归删除文件夹(空文件夹)
17 os.removedirs("a/b/c/d/e/f/g")
os模块具有 新建/删除
技术分享图片 技术分享图片
                 1
                import
                 os,time

                 2
                 3 pathvar = "/mnt/hgfs/day17/abc.py" 4#basename() 返回文件名部分 5 res = os.path.basename(pathvar)
 6print(res)
 7#dirname()  返回路径部分 8 res = os.path.dirname(pathvar)
 9print(res)
1011print(__file__) # /mnt/hgfs/python33_gx/day17/3.py12 res = os.path.dirname(__file__)
13print(res)
1415#split() 将路径拆分成单独的文件部分和路径部分 组合成一个元组16 tup = os.path.split(pathvar)
17print(tup)
1819#join()  将多个路径和文件组成新的路径 可以自动通过不同的系统加不同的斜杠  linux / windows20 path1 = "home"21 path2 = "wangwen"22 path3 = "mysoft"23# 方法一24 pathvar = path1 + os.sep + path2 + os.sep + path3
25print(pathvar)
26# 方法二(推荐)27 pathvar = os.path.join(path1,path2,path3)
28print(pathvar)
2930#splitext() 将路径分割为后缀和其他部分 (了解)31 pathvar = "/mnt/hgfs/.day17/abc.py"32 res = os.path.splitext(pathvar)
33print(res)
3435 res = pathvar.split(".")
36print(res[-1])
3738#getsize()  获取文件的大小 ***39"""getsize只能获取文件大小,不能获取文件夹的大小"""40print(os.getcwd())
41 pathvar = os.path.join(os.getcwd(),"1.txt") # /mnt/hgfs/python33_gx/day17/1.txt42print(pathvar)
43 res = os.path.getsize(pathvar)
44print(res)
4546#isdir()    检测路径是否是一个文件夹 ***47 pathvar = os.path.join(os.getcwd(),"1.txt") # /mnt/hgfs/python33_gx/day17/1.txt48 res = os.path.isdir(pathvar)
49print(res)
50#isfile()   检测路径是否是一个文件 ***51 res = os.path.isfile(pathvar)
52print(res)
53#islink()   检测路径数否是一个链接 **54 res = os.path.islink("/home/wangwen/ceshi03/ceshi01")
55print(res)
565758 os.chdir("/home/wangwen/mysoft/")
59""" stat 文件 => 查看相应的时间 """60#getctime() [windows]文件的创建时间,[linux]权限的改动时间(返回时间戳) **61 res = os.path.getctime("ceshi2.py") 
62print(res) 
63#getmtime() 获取文件最后一次修改时间(返回时间戳) **64 res = os.path.getmtime("ceshi2.py") 
65print(res) 
66#getatime() 获取文件最后一次访问时间(返回时间戳) **67 res = os.path.getatime("ceshi2.py") 
68print(res) 
69# 返回时间字符串70 str_time = time.ctime(res)
71print(str_time)
7273#exists()   检测指定的路径是否存在 ***74 res = os.path.exists("ceshi4.py")
75print(res)
76777879#isabs()    检测一个路径是否是绝对路径 ***80 pathvar = "."81 res = os.path.isabs(pathvar)
82print(res)
8384#abspath()  将相对路径转化为绝对路径 ***85 res = os.path.abspath(pathvar)
86print(res)
8788# 如果不是绝对路径 => 变成绝对路径89"""/开头的是绝对路径,剩下的都是相对路径;"""90 pathvar = "ceshi3.py"91ifnot os.path.isabs(pathvar):
92     res = os.path.abspath(pathvar)
93print(res)
os.path

 

8、shutil模块 复制/移动/

技术分享图片 技术分享图片
                 1
                #
                 1.复制内容
                 2
                #
                 copyfileobj(fsrc, fdst[, length=16*1024])  复制文件 (length的单位是字符(表达一次读多少字符)) (了解)
                 3
                """
                 4
                fp1 = open("lianxi2",mode="r+",encoding="utf-8")

                 5
                fp2 = open("ceshi1.txt",mode="w",encoding="utf-8")

                 6
                shutil.copyfileobj(fp1,fp2)

                 7
                """
                 8
                #
                 copyfile(src,dst)   #单纯的仅复制文件内容 , 底层调用了 copyfileobj  (了解)
                 9 shutil.copyfile("ceshi1.txt","ceshi3.py")
1011# 2.复制权限12# copymode(src,dst)   #单纯的仅复制文件权限 , 不包括内容  (虚拟机共享目录都是默认777)13"""复制权限时,必须文件存在"""14 shutil.copymode("ceshi3.py","lianxi2")
1516# copystat(src,dst)   #复制所有状态信息,包括权限,组,用户,修改时间等,不包括内容17 shutil.copystat("lianxi2","ceshi4.py")
1819# 3.复制内容 + 权限20# copy(src,dst)       #复制文件权限和内容21 shutil.copy("lianxi2","ceshi5.py")
2223# copy2(src,dst)      #复制文件权限和内容,还包括权限,组,用户,时间等24 shutil.copy2("lianxi2","ceshi6.py")
2526# 4.递归拷贝/删除27# copytree(src,dst)   #拷贝文件夹里所有内容(递归拷贝)28 shutil.copytree("ceshi777","ceshi666")
2930# rmtree(path)        #删除当前文件夹及其中所有内容(递归删除)31 shutil.rmtree("ceshi777")
3233# 5.剪切34# move(path1,paht2)   #移动文件或者文件夹35 shutil.move("ceshi1.txt","pycharm-community-2020.1.3/ceshi2.ttt")
View Code

 

技术分享图片 技术分享图片
                 1
                def
                 getallsize(pathvar):

                 2     size = 0
 3     lst = os.listdir(pathvar)
 4for i in lst:
 5# 拼接成完整的绝对路径 6         pathnew = os.path.join(pathvar,i)
 7if os.path.isdir(pathnew):
 8# print("[文件夹]",i) 9             size += getallsize(pathnew)
10elif os.path.isfile(pathnew):
11# print("[文件]",i)12             size += os.path.getsize(pathnew)
1314return size
1516 res = getallsize(pathvar)
17print(res)
计算文件大小

 

9、tarfile 模块 后缀为.tar  |  .tar.gz  |   .tar.bz2

技术分享图片 技术分享图片
                 1
                import
                 tarfile

                 2
                 3
                #
                 ### 1.创建tar包
                 4
                #
                 1.创建压缩包
                 5 tf = tarfile.open("ceshi1210.tar","w",encoding="utf-8")
 6# 2.写入文件 7 tf.add("/bin/cat","cat")
 8 tf.add("/bin/chacl","chacl")
 9 tf.add("/bin/cp","tmp/cp")
10 tf.add("/aaabbb","aaabbb") #可直接压缩文件夹11# 3.关闭文件12 tf.close() # 225,280 1314# ### 2.创建.tar.gz包15 tf = tarfile.open("ceshi1210.tar.gz","w:gz",encoding="utf-8")
16 tf.add("/bin/cat","cat")
17 tf.add("/bin/chacl","chacl")
18 tf.add("/bin/cp","tmp/cp")
19 tf.add("/aaabbb","aaabbb")
20 tf.close() # 96,7972122# ### 3.创建.tar.bz2包23 tf = tarfile.open("ceshi1210.tar.bz2","w:bz2",encoding="utf-8")
24 tf.add("/bin/cat","cat")
25 tf.add("/bin/chacl","chacl")
26 tf.add("/bin/cp","tmp/cp")
27 tf.add("/aaabbb","aaabbb")
28 tf.close() # 840782930# ### 解压文件31 tf = tarfile.open("ceshi1210.tar.bz2","r",encoding="utf-8")
32# 解压所有33# tf.extractall("ceshi1210")34# 解压单个(落脚在文件身上)35 tf.extract("aaabbb/1.py","ceshi1210_1")
36tf.close()
3738# ### 查看文件 (使用with语法)39 with tarfile.open("ceshi1210.tar.bz2","r",encoding="utf-8") as tf:
40     lst = tf.getnames()
41print(lst)
4243# ### 追加文件44"""无法对已经压缩过的压缩包做内容的追加;"""45# with tarfile.open("ceshi1210.tar","a",encoding="utf-8") as tf:46# tf.add("/bin/mv","mv") # success 4748# with tarfile.open("ceshi1210.tar.bz2","a",encoding="utf-8") as tf:49# tf.add("/bin/mv","mv") # error5051# ### 解决办法:52"""531.先解压
542.将文件追加到该文件夹中
553.在重新过滤打包即可
56"""57import shutil,os
58 pathvar = os.getcwd()
59print(pathvar) # /mnt/hgfs/python33_gx/day17/代码60 pathvar1 = os.path.join(pathvar,"ceshi1210.tar.bz2") # /mnt/hgfs/python33_gx/day17/代码/ceshi1210.tar.bz261 pathvar2 = os.path.join(pathvar,"ceshi1210_2")
626364# 1.先解压文件65 with tarfile.open(pathvar1,"r",encoding="utf-8") as tf:
66     tf.extractall("ceshi1210_2")
6768# 2.将文件追加到该文件夹中69 shutil.copy("/bin/nano",pathvar2)
7071# 3.在重新过滤打包即可72"""过滤掉cat,剩下的数据打包"""73 lst = os.listdir(pathvar2)
74print(lst) # [‘aaabbb‘, ‘cat‘, ‘chacl‘, ‘nano‘, ‘tmp‘]757677 with tarfile.open(pathvar1,"w:bz2",encoding="utf-8") as tf:
78for i in lst:
79if i != "cat":
80# 拼接好完整绝对路径81             pathvar = os.path.join(pathvar2,i)
82# 添加到压缩包中83             tf.add(pathvar,i)
View Code

 

四、正则表达式

正则表达式由一些 [普通字符] 和一些 [元字符] 组成:
(1)普通字符包括大小写字母和数字
(2)元字符具有特殊含义,大体种类分为如下:

  1. .预定义字符集,字符组
  2. 量词
  3. 边界符
  4. 分组

语法: lst = re.findall("正则表达式","字符串")

1、匹配单个字符

1..预定义字符集

预定义字符集 匹配内容
. 匹配任意字符,除了换行符n
d 匹配数字
D 匹配非数字
w 匹配字母或数字或下划线 (正则函数中,支持中文的匹配)
W 匹配非字母或数字或下划线
s 匹配任意的空白符
S 匹配任意非空白符
n 匹配一个换行符
t 匹配一个制表符
[] 匹配中括号内列举的字符

 

技术分享图片 技术分享图片
                 1
                #
                 d 匹配数字
                 2 lst = re.findall("d","kjsdkfj2134*&(&你胜多负少")
 3print(lst)
 4 5# D 匹配非数字 6 lst = re.findall("D","kjsdkfj2134*&(&你胜多负少")
 7print(lst)
 8 9# w 匹配字母或数字或下划线     (正则函数中,支持中文的匹配)10 lst = re.findall("w","xboyww 1231 s撒旦法&*()J_H")
11print(lst)
1213# W 匹配非字母或数字或下划线14 lst = re.findall("W","xboyww 1231 s撒旦法&*()J_H")
15print(lst)
1617# s 匹配任意的空白符 (空格 r t n )18 lst = re.findall(s,"    sdf            jkjk  r ")
19print(lst)
2021# S 匹配任意非空白符22 lst = re.findall(S,"    sdf            jkjk  r ")
23print(lst)
2425# n 匹配一个换行符26 strvar = """2711122
28"""29 lst = re.findall(r"n",strvar)
30print(lst)
3132# t 匹配一个制表符33 strvar = """3411122                3434
35"""36 lst = re.findall(r"t",strvar)
37print(lst)
View Code

2.字符组

字符组格式 说明 [默认必须从字符组中选一个]
[...] 匹配字符组中的字符
[^...] 匹配除了字符组内所有内容,之外的所有字符

 

技术分享图片 技术分享图片
                 1 lst = re.findall("[123]","abc1def2zzz3")
 2print(lst)
 3 4print(re.findall(a[abc]b,aab abb acb adb)) # aab abb acb 5 6print(re.findall(a[0123456789]b,a1b a2b a3b acb ayb)) # a1b a2b a3b 7# 优化写法 0123456789 => 0-9 8print(re.findall(a[0-9]b,a1b a2b a3b acb ayb))  # [‘a1b‘, ‘a2b‘, ‘a3b‘] 910print(re.findall(a[abcdefg]b,a1b a2b a3b acb ayb adb)) # acb adb11# 优化写法 abcdefg => a-g 表达所有的小写字母 a-z12print(re.findall(a[a-g]b,a1b a2b a3b acb ayb adb)) 
13print(re.findall(a[a-z]b,a1b a2b a3b acb ayb adb)) # acb ayb adb1415print(re.findall(a[ABCDEFG]b,a1b a2b a3b  aAb aDb aYb)) # aAb aDb16# 优化写法 ABCDEFG => A-G 表达所有的大写字母 A-Z17print(re.findall(a[A-G]b,a1b a2b a3b  aAb aDb aYb))
18print(re.findall(a[A-Z]b,a1b a2b a3b  aAb aDb aYb)) # aAb aDb aYb1920print(re.findall(a[0-9a-zA-Z]b,a-b aab aAb aWb aqba1b))  #  aab aAb aWb  aqb a1b21# 注意点 不能写0-z表达所有的字母+数字 会含有特殊字符22print(re.findall(a[0-z]b,a-b aab aAb aWb aqba1b a@b))  #  aab aAb aWb  aqb a1b a@b2324print(re.findall(a[0-9][*#/]b,a1/b a2b a29b a56b a456b)) # a1/b2526# ^ 在字符组当中,表达除了...的意思 , 27print(re.findall(a[^-+*/]b,"a%b ccaa*bda&bd")) #  a%b a&b
View Code

3.注意点

无论是正则表达式,还是后面字符串,前面写r一定不错

            #
             匹配 ^ - 
strvar = "a^c a-c ac"
lst = re.findall(r"a[^-\]c",strvar)
print(lst)
print(lst[-1])

# b 退格的意思(正则中还有边界符的含义 b同时具有2层含义)
lst = re.findall(r"a\b",r"ab")
# print("ab")print(lst)

 

2、多个字符匹配

1.量词

量词 用法说明
? 重复0次或1次
+ 重复1次或多次 (至少1次)
* 重复0次或多次 (任意次)
{n} 重复n次
{n,} 重复n次或更多次 (至少n次)
{n,m} 重复n到m次
.* .+ 贪婪模式匹配
.*? .+? 非贪婪模式匹配
技术分享图片 技术分享图片
                 1
                ‘‘‘
                1) ? 匹配0个或者1个a 
                ‘‘‘
                 2
                print(re.findall(a?b,abbzab abb aab))  # ab b ab ab b ab 3‘‘‘2) + 匹配1个或者多个a ‘‘‘ 4print(re.findall(a+b,b ab aaaaaab abb)) # ab aaaaaab ab 5‘‘‘3) * 匹配0个或者多个a ‘‘‘ 6print(re.findall(a*b,b ab aaaaaab abbbbbbb)) # b ab aaaaaab ab b b b b b b 7‘‘‘4) {m,n} 匹配m个至n个a ‘‘‘# 1 <= a <= 3 8print(re.findall(a{1,3}b,aaab ab aab abbb aaz aabb)) # aaab ab aab ab aab 9# a字符出现的次数是必须2次10print(re.findall(a{2}b,aaab ab aab abbb aaz aabb)) # aab aab aab11# a字符出现的次数至少2次12print(re.findall(a{2,}b,aaab ab aab abbb aaz aabb)) # aaab aab aab
View Code

2.贪婪匹配 与 非贪婪匹配 [语法:量词的后面加?号]

贪婪模式 : 默认向更多次匹配
回溯算法 : 从左向右一直匹配,直到匹配不到了,在回头,把上一次找到的元素返回;

非贪婪模式 : 默认向更少次匹配

技术分享图片 技术分享图片
                 1 strvar = "刘能和刘老根和刘一手111子222子" 2 lst = re.findall("刘.",strvar) # 刘能 刘老 刘一 3print(lst)
 4 5 lst = re.findall("刘.?",strvar) # 刘能 刘老 刘一 6print(lst)
 7 8 lst = re.findall("刘.+",strvar) # 刘能和刘老根和刘一手111子222子 9print(lst)
1011 lst = re.findall("刘.*",strvar) # 刘能和刘老根和刘一手111子222子12print(lst)
1314 lst = re.findall("刘.{1,30}",strvar) # 刘能和刘老根和刘一手111子222子15print(lst)
1617 lst = re.findall("刘.{1,30}子",strvar) # 刘能和刘老根和刘一手111子222子18print(lst)
贪婪模式
技术分享图片 技术分享图片
                 1 lst = re.findall("刘.??",strvar) # [‘刘‘, ‘刘‘, ‘刘‘] 2print(lst)
 3 4 lst = re.findall("刘.+?",strvar) # 刘能 刘老 刘一 5print(lst)
 6 7 lst = re.findall("刘.*?",strvar) # [‘刘‘, ‘刘‘, ‘刘‘] 8print(lst)
 910 lst = re.findall("刘.{1,30}?",strvar) # 刘能 刘老 刘一11print(lst)
1213 lst = re.findall("刘.{1,30}?子",strvar) # 刘能和刘老根和刘一手111子14print(lst)
非贪婪模式

 

3.边界符 b

只要不是字母数字下划线都可以作为边界;
b
(1) 转义字符 退格
(2) 正则中的边界符

  1. 卡住左边界: bw
  2. 卡住右边界: db
            #
             卡住右边界
strvar = "word pwd book"
lst = re.findall(r"db",strvar)
lst = re.findall(r".*db",strvar)
lst = re.findall(r".*?db",strvar)
print(lst)

# 卡住左边界
strvar = "pwd word book"
lst = re.findall(r"bw",strvar) # [‘w‘]
lst = re.findall(r"bw.*",strvar) # [‘word pwd book‘]
lst = re.findall(r"bw.*?",strvar) # [‘w‘]
lst = re.findall(r"bw.*? ",strvar) # [‘w‘]
lst = re.findall(r"bwS*",strvar) # ["word"]print(lst)

4. ^ 匹配字符串的开始  $匹配字符串的结尾

如果使用了^ 和 $ 必须要把字符串看成一个整体

技术分享图片 技术分享图片
                 1 strvar = "大哥大嫂大爷" 2print(re.findall(大.,strvar))  # [‘大哥‘, ‘大嫂‘, ‘大爷‘] 3print(re.findall(^大.,strvar)) # 大哥 4print(re.findall(大.$,strvar)) # 大爷 5print(re.findall(^大.$,strvar)) # [] 6print(re.findall(^大.*?$,strvar))# 大哥大嫂大爷 7print(re.findall(^大.*?大$,strvar)) # [] 8print(re.findall(^大.*?爷$,strvar)) # 大哥大嫂大爷 910print(re.findall(^g.*?  , giveme 1gfive gay)) #giveme 11print(re.findall(five$ , aassfive)) # five12print(re.findall(^giveme$ , giveme)) # giveme13print(re.findall(^giveme$ , giveme giveme)) # []14print(re.findall(giveme , giveme giveme)) # giveme giveme15print(re.findall("^g.*e",giveme 1gfive gay)) # giveme 1gfive
View Code

3、匹配分组 ()表达一个整体

1、匹配分组 ()

            print(re.findall(.*?_good,wusir_good alex_good secret男_good))#[‘wusir_good‘, ‘ alex_good‘, ‘ secret男_good‘]
# findall  会优先显示括号里面的内容print(re.findall((.*?)_good,wusir_good alex_good secret男_good))#[‘wusir‘, ‘ alex‘, ‘ secret男‘]
# findall  ?: 取消优先显示括号的功能print(re.findall((?:.*?)_good,wusir_good alex_good secret男_good))#[‘wusir_good‘, ‘ alex_good‘, ‘ secret男_good‘]

2、|的使用

lst = re.findall("a|b","sdhfjha234234bkjkjk")
print(lst) # [‘a‘, ‘b‘]# 注意点: 把较难匹配的内容放到前面,容易匹配的内容放到后面,才能保证所有元素都能匹配到;
lst = re.findall("abc|abcd","12342abcdjskdfjkabc")
print(lst) # ["abc","abc"]
lst = re.findall("abcd|abc","12342abcdjskdfjkabc")
print(lst) # [‘abcd‘, ‘abc‘

3、search

obj.group() => 获取匹配到的内容
obj.groups() => 获取分组中的内容

findall : 优点:从左到右匹配,找到所有的内容,返回到列表
缺点:匹配的内容和分组的内容不能同时显示在同一个界面中

search : 缺点:从左到右匹配,匹配到第一个满足条件的内容直接返回,最后返回的是对象
优点:可以把分组里的内容和匹配到的内容同时显示在同一个界面中

obj = re.search("(www).(baidu|oldboy).(com)",strvar)
print(obj)
# 获取匹配到的内容
res = obj.group()
print(res)
# 获取分组中的内容
# 方法一 (推荐)
res = obj.groups()
print(res)
# 方法二
res = obj.group(1)
print(res)
res = obj.group(2)
print(res)
res = obj.group(3)
print(res)

 

4、反向引用

            #
             把第一个括号里面的数据放到1在引用一次;
obj = re.search(r"<(.*?)>(.*?)<(/1)>",strvar)
print(obj)
print(obj.group())
print(obj.groups())

strvar = "a1b2cab z4y5gzy"
obj = re.search(r"(.*?)d(.*?)d(.*?)(1)(2)",strvar)
print(obj.group()) # a1b2cabprint(obj.groups())

5、命名分组

?P<组名>正则表达式) 给这个组起一个名字

(?P=组名) 引用之前组的名字,把该组名匹配到的内容放到当前位置

            #
             方法一
obj = re.search(r"(?P<tag1>.*?)d(?P<tag2>.*?)d(?P<tag3>.*?)(1)(2)",strvar)
print(obj)
print(obj.group())
print(obj.groups())

# 方式二
obj = re.search(r"(?P<tag1>.*?)d(?P<tag2>.*?)d(?P<tag3>.*?)(?P=tag1)(?P=tag2)",strvar)
print(obj)
print(obj.group())
print(obj.groups())

6、正则函数

1.search

通过正则匹配出第一个对象返回,通过group取出对象中的值 ,通过groups取出分组当中的数据

2.match

search 和 match 使用时一模一样,区别在于在search正则表达式的开头加上^ 等价于 match 

3.split 切割

strvar = "alex2674623wusir22xboyww55555risky"
res = re.split("d+",strvar)
print(res)

4.sub      替换 

sub(正则表达式,替换的元素,替换的原字符串[,替换的次数])

strvar = "alex_wusir|xboyww&risky"
res = re.sub("[_|&]","@",strvar,2)
print(res)

subn     替换

subn 对比 sub 只是在返回值有所不同,返回的是元组(字符串,替换次数)

strvar = "alex_wusir|xboyww&risky"
res = re.subn("[_|&]","@",strvar)
print(res) # (‘alex@wusir@xboyww@risky‘, 3)

5、finditer 匹配字符串中相应内容,返回迭代器

            from collections import Iterator,Iterable
strvar = "sdf234sdfjkhj&^&*^987"
it = re.finditer("d",strvar)
print(isinstance(it,Iterator))
for i in it:
    # print(i)print(i.group())

6、compile 指定一个统一的匹配规则

可以制定一次正则表达式,编译一次,终身受益,不需要反复编译,提升执行效率

pattern = re.compile("d")
print(pattern)
strvar = "sdf234sdfjkhj&^&*^987"# search的使用
obj = pattern.search(strvar)
print(obj.group())
# findall的使用
res = pattern.findall(strvar)
print(res

7、修饰符

常用修饰符 说明
re.I 使匹配对大小写不敏感
re.M 使每一行都能够单独匹配(多行匹配),影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符

 

技术分享图片 技术分享图片
                 1
                #
                 (1) re.I 使匹配对大小写不敏感
                 2 strvar = "<h1>我是大标题</h1>" 3 pattern = re.compile("<h1>(.*?)</H1>" , flags = re.I)
 4 obj = pattern.search(strvar)
 5print(obj)
 6print(obj.group())
 7print(obj.groups())
 8 9# (2) re.M 使每一行都能够单独匹配(多行匹配),影响 ^ 和 $10 strvar = """11<a>我是连接</a>
12<p>我是段落</p>
13<div>我是盒子</div>
14"""1516 pattern = re.compile("^<.*?>.*?<.*?>$",flags = re.M)
17 lst = pattern.findall(strvar)
18print(lst)
19# print(obj)20# print(obj.group())212223# (3) re.S 使 . 匹配包括换行在内的所有字符24 strvar = """25please give 
26234234mefive
27"""28 pattern = re.compile(".*?mefive" , flags=re.S)
29 obj = pattern.search(strvar)
30print(obj)
31print(obj.group()) # 234234mefive
View Code

(扩展) 如果想要所有的修饰符 使用 | 进行拼接

pattern = re.compile(".*?mefive" , flags=re.S|re.M|re.I)
obj = pattern.search(strvar)
print(obj)

 

原文:https://www.cnblogs.com/yj0405/p/14113456.html


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!

相关教程推荐

其他课程推荐