python学习笔记13

python学习笔记13

re模块中的方法
  • split

    # 根据正则表达式切割指定字符
    import re
    ret = re.split('\d+','abc12def')
    print(ret) # ['abc', 'def']
    # 对正则表达式加上括号可以在切割结果中将切割项显示出来
    ret1 = re.split('(\d+)','abc12def')
    print(ret1) # ['abc', '12', 'def']
    
  • sub

    # 用指定内容替换正则表达式匹配到的内容
    import re
    ret = re.sub('\d+','x','abc12def34')
    print(ret) # abcxdefx
    
    # 可以输入参数控制要替换的个数
    ret1 = re.sub('\d+','x','abc12def34',1)
    print(ret1) # abcxdef34
    
  • subn

    # 在sub的基础上输出一个替换数量的信息
    import re
    ret = re.subn('\d+','x','abc12def34ghi56')
    print(ret) # ('abcxdefx', 3)
    
  • match

    # 匹配字符内容的头部信息
    import re
    ret = re.match('\d+','abc12def34ghi56')
    print(ret) # None
    ret1 = re.match('\d+','12abc3def4ghi56')
    print(ret1) # <re.Match object; span=(0, 2), match='12'>
    print(ret1.group()) # 12
    
    """
    match:规定字符串必须是什么格式
    search:寻找字符串中是否有满足条件的部分
    """
    
  • compile:节省时间

    # 对正则表达式进行解析
    import re
    # 当同一个正则表达式要被使用多次时,可以先对其进行compile编译再操作
    # 可以节省多次解析同一个正则表达式的时间
    ret = re.compile('\d+')
    res1 = ret.findall('abc1de2f3')
    print(res1) # ['1', '2', '3']
    res2 = ret.search('abc1de2f3')
    print(res2) # <re.Match object; span=(3, 4), match='1'>
    
  • finditer:节省空间

    import re
    ret = re.finditer('\d+','abc18de2f3g456')
    for i in ret:
        print(i)
        print(i.group())
    """
    <re.Match object; span=(3, 4), match='1'>
    18
    <re.Match object; span=(6, 7), match='2'>
    2
    <re.Match object; span=(8, 9), match='3'>
    3
    <re.Match object; span=(10, 13), match='456'>
    456
    """
    
re模块的用法
# 给分组命名
import re
ret = re.search('\d(\d)(\w+?)(\d)(\w+?)\d(\d)(\w+?)(\d)','112132r334121agcuay6s8a7ssaiu38683he78as7c_32893hf93y73f')
print(ret) # <re.Match object; span=(0, 11), match='112132r3341'>
# 当需要获取某个指定分组的内容时,可以修改上述代码如下
ret1 = re.search('\d(\d)(\w+?)(\d)(?P<name>\w+?)\d(\d)(\w+?)(\d)','112132r334121agcuay6s8a7ssaiu38683he78as7c_32893hf93y73f')
print(ret1.group('name')) # 32r

在用正则表达式进行字符匹配时,有时候会遇到具有特殊意义的转义字符的匹配,这时候正则表达式需要对其进行处理消除转义字符的特殊意义:可以在每个具有特殊意义的转义字符前加上一个\或者可以在字符串'string'前加上一个r表示消除转义r'string'

带参数的修饰器

当我们在需要对不同函数进行同一修饰时,可以用同一个修饰器对其进行修饰。但是当我们需要控制其内部细微差异时(比如控制对不同函数要创建不同的文件,并向其中写入内容),则需要用到带参数的修饰器来控制其之间的差别。

# 比如我们有一个修饰其可以打印出函数运行时间
import time
def logger(func):
    def inner(*args,**kwargs):
        ret = func(*args,**kwargs)
        print("%s执行了%s"%(time.strftime('%Y-%m-%d %H:%M:%S'),func.__name__))
        return ret
    return inner
@logger
def f1():
    print('function1')
@logger
def f2():
    print('function2')

f1() 
# function1
# 2020-03-30 10:39:41执行了f1
f2()
# function2
# 2020-03-30 10:39:41执行了f2

# 但是当我们需要将每个函数的工作时间打印到每个函数专属的文件时
# 操作就不是那么简单了,虽然可以使用if语句判定来执行操作
# 但是当需要修饰的函数过多时就显得特别复杂
# 这个时候就需要带参数的修饰器来实现这样的功能
# 带参数的修饰器
import time
def logger(path):
    def log(func):
    	def inner(*args,**kwargs):
        	ret = func(*args,**kwargs)
            with open(path,mode='a',encoding='utf-8') as f:
                msg = "%s执行了%s"%(time.strftime('%Y-%m-%d %H:%M:%S'),func.__name__)
                f.write(msg)
        	return ret
    	return inner
    return log
# 这样的修饰器就可以实现上面要求的功能

# 修饰器的调用也需要带入参数
@logger('file_path1')
def f1():
    print('function1')
@logger('file_path2')
def f2():
    print('function2')
递归函数

在python中,官方规定递归的最大深度为1000层。

  1. 递归要尽量控制次数,一个需要很多层递归才能解决的问题往往不适合用递归解决。

  2. 循环和递归的关系

    递归不是万能的;递归比循环更加占用内存

  3. python中修改递归的最大深度

    import sys
    sys.setrecursionlimit(100000) # 修改为100000次
    # 但是一般计算机递归会有一个最大值
    
  4. 一个递归函数想要结束,必须在函数内部有一个return,并且return的条件是可以达到的。

递归示例:

# 编写一个函数,其可以打印出一个文件夹下的所有文件
import os 
def show_file(path):
    name_lst = os.listdir(path)
    for name in name_lst:
        abs_path = os.path.join(path,name)
        if os.path.isfile(abs_path):
            print(abs_path)
        else:
            show_file(abs_path)
posted @ 2020-03-30 12:09  卡奇欧  阅读(113)  评论(0)    收藏  举报