The Wasu Auto TestFrameWork
Project description
打包
python3 setup.py sdist bdist_wheel
上传
twine upload dist/*
# TODO
添加todo
单例模式
# 单例模式
def singleton(cls):
_instance = {}
def inner():
if cls not in _instance:
_instance[cls] = cls()
return _instance[cls]
return inner
带参数的单例(错误示范) 具体原因待查
# 单例模式
def singleton(cls, *args, **kw):
_instance = {}
def inner():
if cls not in _instance:
_instance[cls] = cls(*args, **kw)
return _instance[cls]
return inner
带参数的单例(正确示范)
def singleton(cls):
_instance = {}
def inner(*args, **kw):
if cls not in _instance:
_instance[cls] = cls(*args, **kw)
return _instance[cls]
return inner
使用pathlib.Path
判断文件是否存在
pip install -r requirement.txt
pip freeze > requirements.txt
聊聊装饰器(上)
项目中遇到的一个装饰器的问题,发现对装饰器这块理解有偏差,写一篇文章做个记录
我们人类现在有两个行为方法,先来实现一下
def eat():
print("eating")
def drink():
print("drinking")
if __name__ == "__main__":
print(eat)
print(eat())
首先要理解一下这里eat
和eat()
的区别,打印一下看看
返回结果如下:
<function eat at 0x7f95378d5ee0>
eating
None
可以看到eat
打印出来一个方法对象的内存地址,说明这是一个函数对象。而eat()
则执行了print
的操作,由于没有返回值
则返回了一个None
。这里的区别就是eat
代表了一个方法对象,而
eat()
则是调用了方法的执行。
那么在面向对象的思想中,我们可以知道对象可以传递,比如将eat
这个方法传递给一个变量new_eat
,修改下代码看看
print(eat)
new_eat = eat
print(new_eat())
运行,发现返回结果还是和之前一样。可以证实刚才得到的结论。
现有有个需求方又对我们人类提出了新的需求,每次吃饭喝水前都要洗手。简单,直接在前面加个方法就可以了
def wash_hands():
print("washing hands")
def eat():
wash_hands()
print("eating")
def drink():
wash_hands()
print("drinking")
if __name__ == "__main__":
eat()
drink()
实现好了,需求方拒绝了,因为我们修改了他们原来的方法,不仅麻烦还容易出问题。 看着这段话,是不是想到了Java中的AOP,那么在Python该怎么办? 既然我们最开始知道了方法的传递,是不是可以利用一下?实现如下:
def wash_hands(func):
print("washing hands")
func()
def eat():
print("eating")
def drink():
print("drinking")
if __name__ == "__main__":
wash_hands(eat)
wash_hands(drink)
我们可以调用wash_hands
这个方法,同时将方法作为一个参数传入,在方法中再进行调用,而且还没有修改原来的代码逻辑。
这样子岂不是轻轻松松解决了?
需求方还没完,又来说了,你虽然没改了我的代码,但是我一开始调用的是eat
方法,可是你现在全变成wash_hands
方法了,这不行啊!
emmm,行吧,谁叫需求是爹呢?我们再来优化一下,我们可以借鉴刚才的传递方法的方式,再来写一个方法:
def wash_hands():
print("washing hands")
def wrapper(func):
def inner():
wash_hands()
func()
return inner
def eat():
print("eating")
def drink():
print("drinking")
if __name__ == "__main__":
eat = wrapper(eat)
eat()
我们来梳理一下这段代码的逻辑,wrapper(eat)
接受了一个eat
方法的参数,所以会先运行wrapper(eat)
,这个方法中还定义了一个方法
inner()
,但是我们并没有调用它,所以直接执行最后一句return inner
,而inner也是一个方法,所以返回后赋值给eat
的时候,
eat
也变成了一个方法,既然是一个方法,我们就可以用eat()
的形式去调用它。(这里调用的并不是原来的eat()
方法,
实际上是inner()
方法,为什么不会调用原来的方法和Python的运行机制有关,这里暂不讨论)。可以看到我们最后调用的时候,给eat
外面加了一个
wrapper
,看起来像被包裹了起来,所以把它称之为装饰器,Python也给出了一个语法糖,可以在方法上直接使用@wrapper
,就像这样
@wrapper
def eat():
print("eating")
这个就等同与 wrapper(eat)
,
这时候我们只需要直接调用eat()
方法即可。
需求方看了看,又再一次发出了质疑,如果不同的人吃饭我有不同的服务呢?
加个参数不就行了,由于我们之前实际调用的都是inner
,所以我们也要加上参数。但是如果是他人的方法,写了一大堆参数,咋整?
来,把全宇宙最无敌的参数拿出来,*args,**kwargs
, 还有什么参数摆不平?
需求方一脸严肃,又准备开始提需求了.....
剩下的下回再说吧,待更新...
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.