Python 相当于 golang 的 defer 语句

如何实现类似于deferPython 中 go 语句的功能?


Defer 将函数调用压入堆栈。当包含 defer 语句的函数返回时,延迟的函数调用会在 defer 语句最初所在的作用域内一个一个地弹出并执行。Defer 语句看起来像函数调用,但在弹出之前不会执行。


去看看它是如何工作的例子:


func main() {

    fmt.Println("counting")


    var a *int

    for i := 0; i < 10; i++ {

        a = &i

        defer fmt.Println(*a, i)

    }


    x := 42

    a = &x


    fmt.Println("done")

}

输出:


counting

done

9 9

8 8

7 7

6 6

5 5

4 4

3 3

2 2

1 1

0 0

Go 用例示例:


var m sync.Mutex

func someFunction() {

    m.Lock()

    defer m.Unlock()

    // 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.

}


肥皂起泡泡
浏览 310回答 3
3回答

一只甜甜圈

要模拟defer fmt.Println(*a, i)示例,您可以使用contextlib.ExitStack:#!/usr/bin/env python3from contextlib import ExitStackfrom functools import partialprint("counting")with ExitStack() as stack:&nbsp; &nbsp; for i in range(10):&nbsp; &nbsp; &nbsp; &nbsp; a = i&nbsp; &nbsp; &nbsp; &nbsp; stack.callback(partial(print, a, i))&nbsp; &nbsp; x = 42&nbsp; &nbsp; a = x&nbsp; &nbsp; print("done")输出countingdone9 98 87 76 65 54 43 32 21 10 0很容易模拟互斥锁的情况:def some_function(lock=Lock()):&nbsp; &nbsp; with lock:&nbsp; &nbsp; &nbsp; &nbsp; # whatever

饮歌长啸

Python 的with 语句与 Go 的 defer 有类似的用途。Python中类似的代码是:mutex = Lock()def someFunction():&nbsp; &nbsp; with mutex:&nbsp; &nbsp; &nbsp; &nbsp; # Whatever you want, with as many return statements&nbsp; &nbsp; &nbsp; &nbsp; # as you want, wherever. Simply forget that you ever&nbsp; &nbsp; &nbsp; &nbsp; # locked a mutex, or that you have to remember to&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; # release it again.

杨魅力

我在那里制作了一个(与 2.x 兼容):@defers_collectordef func():&nbsp; &nbsp; f = open('file.txt', 'w')&nbsp; &nbsp; defer(lambda: f.close())&nbsp; &nbsp; defer(lambda : print("Defer called!"))&nbsp; &nbsp; def my_defer():&nbsp; &nbsp; recover()&nbsp; &nbsp; defer(lambda: my_defer())&nbsp; &nbsp; print("Ok )")&nbsp; &nbsp; panic("WTF?")&nbsp; &nbsp; print("Never printed (((")func()print("Recovered!")来源defers_collector是:# Go-style error handlingimport inspectimport sysdef panic(x):&nbsp; &nbsp; raise Exception(x)def defer(x):&nbsp; &nbsp; for f in inspect.stack():&nbsp; &nbsp; if '__defers__' in f[0].f_locals:&nbsp; &nbsp; &nbsp; &nbsp; f[0].f_locals['__defers__'].append(x)&nbsp; &nbsp; &nbsp; &nbsp; breakdef recover():&nbsp; &nbsp; val = None&nbsp; &nbsp; for f in inspect.stack():&nbsp; &nbsp; loc = f[0].f_locals&nbsp; &nbsp; if f[3] == '__exit__' and '__suppress__' in loc:&nbsp; &nbsp; &nbsp; &nbsp; val = loc['exc_value']&nbsp; &nbsp; &nbsp; &nbsp; loc['__suppress__'].append(True)&nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; return valclass DefersContainer(object):&nbsp; &nbsp; def __init__(self):&nbsp; &nbsp; # List for sustain refer in shallow clone&nbsp; &nbsp; self.defers = []&nbsp; &nbsp; def append(self, defer):&nbsp; &nbsp; self.defers.append(defer)&nbsp; &nbsp; def __enter__(self):&nbsp; &nbsp; pass&nbsp; &nbsp; def __exit__(self, exc_type, exc_value, traceback):&nbsp; &nbsp; __suppress__ = []&nbsp; &nbsp; for d in reversed(self.defers):&nbsp; &nbsp; &nbsp; &nbsp; try:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; d()&nbsp; &nbsp; &nbsp; &nbsp; except:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; __suppress__ = []&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exc_type, exc_value, traceback = sys.exc_info()&nbsp; &nbsp; return __suppress__def defers_collector(func):&nbsp; &nbsp; def __wrap__(*args, **kwargs):&nbsp; &nbsp; __defers__ = DefersContainer()&nbsp; &nbsp; with __defers__:&nbsp; &nbsp; &nbsp; &nbsp; func(*args, **kwargs)&nbsp; &nbsp; return __wrap__
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go