Week_six_summary

磁盘

Week_six_summary_第1张图片

文件操作-open

base64-优化版

一,将字符串每三位一断,技巧start步长为3
二,每取三位字符串,进行数字转换,并且判断尾部特殊情况,碰见不足3位的字符串,补’\x00’
三,字节序列,第一次右移18位,第二次右移12位,第三次右移6位,第四次右移0位(变为4个字节),bytearry连接(可变)
四,每右移一次,与0x3F(63)位与,取字节序列后六位,其余位归零
五,特殊字符补位的地方更换为’=’
六,转为不可变的bytes
七,使用函数
八,易混点:字符串为1位,base64取高位6位,剩余低位2位放入下一个字节作为高位,且后面补零,这两位有意义。 后面12个字节全部为0,都是补零位,所以无意义,这两位需要替换为’=’,故补两个字符,base64也补两个’=’,缺一个字符也是如此。

import string
def alphabet():
    alphabet = (string.ascii_uppercase + string.ascii_lowercase + string.digits + '+' + '\\').encode()
    return alphabet

def base64(text:str):
    if not isinstance(text,str):  # 如果text不是字符串,抛TypeError错误
        raise TypeError('Expect type is str')
        
    alph = alphabet()      # 调用全局函数
    length = len(text)    
    b_arry = bytearray()    # bytearray可变,用于存放处理后的字节
    
    for start in range(0,length,3):  # start步长3
        triple = text[start:start+3]  # 3步以取
        
        r = 3 - len(triple)   # 判断需要补一位还是补两位
        if r:  # 如果r不为0,需要补位,1个字符补2位,2个字符补1位
            triple += '\x00' * r  # '\x00'在ascii中为0
        
        b = int.from_bytes(triple.encode(),'big')  # 取triple的十进制,进行位与运算,字节序列不能位运算
        for i in range(18,-1,-6): # 3 * 8 24位变为 4 * 6位,4位循环4次,第一次右移6位,得最高位6位
#             if i == 18 :      # 如果i == 18,不需要位与
#                 index = b >> i
#             else:         # 0x3F为63,二进制为111111,某个数与其位与低六位不变,其余高位全部归零,位与有0出0
#                 index = b >> i & 0x3F
            index = b >> i if i== 18 else b >> i & 0x3F
            b_arry.append(alph[index])   # 将处理后得字节,一次放入bytearray
    
    if r:  # 补位处理,切片赋值,补几位'\x00',换几个'=',此处为字节,所以是b'='
        b_arry[-r:] = b'=' * r  
    
    return bytes(b_arry)

cache-优化

一、创建一个字典,为每一个传入的实参都配上形参名,需要通过inspect模块获得函数签名的Parameter对象
二、有缺省值,直接创建缺省值的kv对,无缺省值,等待函数调用配kv对
三、字典使用:a、使用普通字典,kv对全部配完后,排序转为tuple.b、使用OrderDict,配对完直接转为tuple
四、判断key是不在cache中,在则直接返回value,否则调用fn函数,并且将kv对放入caceh字典中
五、cache字典需要使用闭包,而且不同的函数需要不同的字典,不能混在一起

def cache(fn):
#     print('1','cache')
    cache = {}     # 闭包,每次wrapped调用,字典不消亡。而且,每装饰一个wrapped,生成一个新的字典
    cache_get = cache.get  # 方法赋值
    cache_update = cache.update  # 方法赋值
    
    @wraps(fn)  # 将wrapped的属性赋值变成wrapper的属性
    def wrapper(*args,**kwargs):
#         print('4','cache wrapper')
        target = {}  # key存放的目标字典
        target_update = target.update   # key字典更新方法的赋值
#         sig = signature(fn)   
        params = signature(fn).parameters  # 得到wrapped函数的签名参数OrderDict
#        params_name = list(params.keys())  # 将wrapped的参数名字放入列表,一一对应传入的位置参数
#        print(params_name)
        
#         for i,val in enumerate(args):  # 遍历位置参数(元组),并且得到索引号
#             key = params_name[i]       # target配kv对,key为位置实参对应的形参变量名
#             target[key] = val          # val为传入的实参值,组成kv对放入字典target
        target_update(zip(params.keys(),args))  # 优化版1,通过zip拉链函数,生成二元组,通过update(类似于dict(iterable)
                                              # 的构建方式)将其更新到target_update中,params为有序字典,直接使用
          
#         for k,v in kwargs.items():
#             target[k] = v
#             print(cache)
        #target_update(kwargs) # 优化版3,将kwargs update(类似于dict(mapping,dict)的构建方式)到target中
        target_update(**kwargs) # 优化版2,将kwrags解构,update(类似于dict(**kwargs)的构建方式)到target中
        # cache_update = dict(zip(params_name,args),**kwargs)   # 最终版:将优化版1和2结合,直接dict,类似于字典的构建
                                                                # 方式dict(iterable,**kwargs)
            
        for k in (params.keys() - target.keys()): # 集合差值,如果差值不为空,说明有参数使用了缺省值,为空则实参全部传入
            target[k] = params[k].default   # Parameter的缺省值作为v,k为缺省值变量名,组成kv对
    
    
        key = tuple(sorted(target.items()))  # 字典无序,排序转为元组,作为cache的key
        
#         if key in cache:
#             return cache[key]
#         else:
#             ret = fn(*args,**kwargs)
#             cache[key] = ret
        if key not in cache.keys():    # 优化:如果key不在cache的keys中,添加kv对
            cache[key] = fn(*args,**kwargs)

        return cache[key]   # 在或者不在cache中,都返回key对应的值,一定是fn(*args,**kwargs)
    return wrapper

你可能感兴趣的:(summary)