[英]Python decorator
from random import randint
import time
state = 0 #close
open_time = 0
failure_count = 0
count = 0
status = {0 : "closed" , 2 : " open" , 1 : "half closed"}
def circuitbreaker(func):
global count
global open_time , state
print("circuit status "+ status.get(state))
if state ==0: #close state
try:
func()
except Exception as ex:
print(ex)
count+=1
if count>2:
print("opening circuit breaker")
state = 2
open_time = int(time.time())
elif (state == 2): #open state
if( time.time() - open_time > 5) :
state = 1
else:
print("circuit opened")
else:
try:
func()
count = 0
open_time = 0
print("closing circuit breaker")
state = 0
except Exception as ex:
state = 2
open_time = int(time.time())
print("opening circuit breaker")
@circuitbreaker
def generic_func():
a = randint(0,9)
print("hello")
print("random number = "+str(a))
if a>4:
return a
else:
raise Exception('Yalla!')
if __name__=="__main__":
# while(True):
# generic_func()
time.sleep(1)
我有这个代码。 我有几个问题:-1)为什么即使在main中注释了泛型函数也被调用?
2)当我取消注释主要功能部分。 我收到以下错误。如何正确调用此泛型函数。 我的动机是实现一个断路器,该断路器在调用函数中出现某种错误或异常时闭合。 我可以直接使用:-circuitbreaker(calling function)但我想使用装饰器
Traceback (most recent call last):
circuit status closed
hello
File "/Users/abhishekkumar/PycharmProjects/RateLimiter/circuitbreaker.py", line 53, in <module>
random number = 1
Yalla!
generic_func()
TypeError: 'NoneType' object is not callable
Process finished with exit code 1
问题是装饰器应该返回一个函数对象,并且应该在函数内部具有相关的逻辑,然后返回该函数,否则它将不返回任何对象
问题1的答案:这是因为断路器装饰器,因为其逻辑是在模块导入期间执行的,并调用了装饰的功能。 查看以下几行
...
try:
func() # <-- here
except Exception as ex:
print(ex)
...
实现装饰器的方法是返回一个包装函数,其中包含业务逻辑:
from functools import wraps
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
... your logic here ...
return wrapper
问题2的答案来自上一个。
装饰某物的函数应该返回它本身所做的功能- 不做所有事情-您不是在返回“功能指针”,而是从清除程序中隐式返回None
(隐式为None
返回值)。 然后将此None
称为...
怎么修:
def circuitbreaker(func):
def the_works():
global count
global open_time , state
print("circuit status "+ status.get(state))
# .. all your other code ...
return the_works
for _ in range(5):
generic_func()
修复输出 :
circuit status closed
hello
random number = 3
Yalla!
circuit status closed
hello
random number = 3
Yalla!
circuit status closed
hello
random number = 0
Yalla!
opening circuit breaker
circuit status open
circuit opened
circuit status open
circuit opened
circuitbreaker
,您已经调用了generic_func
。 这是Fluent Python的示例:
registry = []
def register(func):
print('running register(%s)' % func)
registry.append(func)
return func
@register
def f1():
print('running f1()')
@register
def f2():
print('running f2()')
def f3():
print('running f3()')
def main():
print('registry ->', registry)
f1()
f2()
f3()
if __name__ == '__main__':
main()
输出是
running register(<function f1 at 0x1055ae378>)
running register(<function f2 at 0x1055ae400>)
registry -> [<function f1 at 0x1055ae378>, <function f2 at 0x1055ae400>]
running f1()
running f2()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.