为了账号安全,请及时绑定邮箱和手机立即绑定

Python 相当于 golang 的 defer 语句

Python 相当于 golang 的 defer 语句

Go
肥皂起泡泡 2021-12-06 19:31:19
如何实现类似于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")}输出:countingdone9 98 87 76 65 54 43 32 21 10 0Go 用例示例:var m sync.Mutexfunc 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.}
查看完整描述

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


查看完整回答
反对 回复 2021-12-06
?
饮歌长啸

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.


查看完整回答
反对 回复 2021-12-06
?
杨魅力

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__


查看完整回答
反对 回复 2021-12-06
  • 3 回答
  • 0 关注
  • 309 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信