Python散文想法

python 代理模式和装饰器总结

2021-11-14  本文已影响0人  Cache_wood

@[toc]

代理模式

proxy pattern
常见类型

装饰器

函数式编程
高阶函数
list(map(f,[x1, x2, x3, x4]))=[f(x1),f(x2),f(x3),f(x4)]
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
list(filter(f,[x1,x2,x3,x4]))=[x for x in [x1,x2,x3,x4] if f(x)]

举例

返回函数
##惰性函数
def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum
f = lazy_sum(1, 3, 5, 7, 9)
print(f)
print(f())
<function lazy_sum.<locals>.sum at 0x000001D4B49CDEE0>
25

对惰性函数的理解:因为惰性函数自身嵌套了子函数,所以在调用惰性函数时,实际上是调用了子函数,子函数的结果返回但不会输出。 这样在不必要的时候我们可以避免输出。

偏函数

为简化多参数函数的调用,可通过固定某参数来返回新函数,以实现简化调用。

import functools

def growth(step=1,limit=200):
    g=0
    while(True):
        if g+step>limit:
            break
        g += step
    return g
print(growth())
print(growth(step=3))
growth3=functools.partial(growth,step=3)
print(growth3())
print(growth3(limit=300))
200
198
198
300
闭包

返回函数不宜引用任何循环变量,或者后续会发生变化的变量

def count():
    fs = []
    for i in range(1, 4):
        def f():
            return i
        fs.append(f)
        print(fs)
    return fs
f1, f2, f3 = count()
print(f1())
print(f2())
print(f3())
#每次存储的是子函数本身,并没有调用,结果相同
3
3
3
def count():
    def f(j):
        def g():
            return j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i)) 
    return fs
f1,f2,f3=count()
print(f1())
print(f2())
print(f3())
#增加一层子函数,每次存储最内层函数的调用实例,f(i)立刻被执行,所以返回每次不同的结果
1
2
3
装饰器

在不修改原始代码的前提下增强或扩展既有功能

def log(func):
    def wrapper(*args,**kwargs):
        print("call " + func.__name__)#额外的功能
        return func(*args,**kwargs) #调用原功能
    return wrapper
@log #使用装饰器
def now():
    pass
now()  #相当于log(now)()

call now

通过装饰器后函数名称发生了变化
保持不变化,需要

functools.wraps(func)

@wraps复制了函数名称、注释文档、参数列表等,使得能够在装饰器里访问在装饰之前的函数属性

在实现装饰器时应在wrapper函数前加入@wraps,避免因函数内部功能逻辑对函数属性的依赖而导致功能错误

装饰器类
from functools import wraps

class Log:
    def __init__(self,logfile='out.log'):
        self.logfile=logfile

    def __call__(self,func):
        @wraps(func)
        def wrapper(*args,**kwargs):
            info="INFO: "+func.__name__+" was called"
            with open(self.logfile,'a') as file:
                file.write(info+'\n')
            return func(*args,**kwargs)
        return wrapper
@Log('test.log')#@Log()
def myfunc():
    pass
myfunc()#相当于Log('test.log')(myfunc)()

INFO: myfunc was called
装饰器的顺序
property

使实例方法的调用如同实例属性

@property #读取属性
@方法名.setter #修改属性
@方法名.deleter #删除属性

也可通过property()方法获取,设置,删除,描述文档

id = property(get_id, set_id, del_id, 'id is ……')
类方法与静态方法
上一篇 下一篇

猜你喜欢

热点阅读