3 回答
TA贡献1836条经验 获得超5个赞
要模拟defer fmt.Println(*a, i)示例,您可以使用contextlib.ExitStack:
#!/usr/bin/env python3
from contextlib import ExitStack
from functools import partial
print("counting")
with ExitStack() as stack:
for i in range(10):
a = i
stack.callback(partial(print, a, i))
x = 42
a = x
print("done")
输出
counting
done
9 9
8 8
7 7
6 6
5 5
4 4
3 3
2 2
1 1
0 0
很容易模拟互斥锁的情况:
def some_function(lock=Lock()):
with lock:
# whatever
TA贡献1951条经验 获得超3个赞
Python 的with 语句与 Go 的 defer 有类似的用途。
Python中类似的代码是:
mutex = Lock()
def someFunction():
with mutex:
# Whatever you want, with as many return statements
# as you want, wherever. Simply forget that you ever
# locked a mutex, or that you have to remember to
# release it again.
TA贡献1811条经验 获得超6个赞
我在那里制作了一个(与 2.x 兼容):
@defers_collector
def func():
f = open('file.txt', 'w')
defer(lambda: f.close())
defer(lambda : print("Defer called!"))
def my_defer():
recover()
defer(lambda: my_defer())
print("Ok )")
panic("WTF?")
print("Never printed (((")
func()
print("Recovered!")
来源defers_collector是:
# Go-style error handling
import inspect
import sys
def panic(x):
raise Exception(x)
def defer(x):
for f in inspect.stack():
if '__defers__' in f[0].f_locals:
f[0].f_locals['__defers__'].append(x)
break
def recover():
val = None
for f in inspect.stack():
loc = f[0].f_locals
if f[3] == '__exit__' and '__suppress__' in loc:
val = loc['exc_value']
loc['__suppress__'].append(True)
break
return val
class DefersContainer(object):
def __init__(self):
# List for sustain refer in shallow clone
self.defers = []
def append(self, defer):
self.defers.append(defer)
def __enter__(self):
pass
def __exit__(self, exc_type, exc_value, traceback):
__suppress__ = []
for d in reversed(self.defers):
try:
d()
except:
__suppress__ = []
exc_type, exc_value, traceback = sys.exc_info()
return __suppress__
def defers_collector(func):
def __wrap__(*args, **kwargs):
__defers__ = DefersContainer()
with __defers__:
func(*args, **kwargs)
return __wrap__
- 3 回答
- 0 关注
- 309 浏览
添加回答
举报