Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python equivalent of golang's defer statement

How would one implement something that works like the defer statement from go in python?

Defer pushes a function call to a stack. When the function containing the defer statement returns, the defered function calls are popped and executed one by one, in the scope that the defer statement was inside in the first place. Defer statements look like function calls, but are not executed until they are popped.

Go example of how it works:

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") } 

Outputs:

counting done 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 

Go example of a usecase:

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. } 
like image 795
Filip Haglund Avatar asked Jan 06 '16 03:01

Filip Haglund


People also ask

Does Python have a defer function?

defer — The defer module. Small framework for asynchronous programming. The Deferred allows to chain callbacks. There are two type of callbacks: normal callbacks and errbacks, which handle an exception in a normal callback.

What is defer in Python?

Defer pushes a function call to a stack. When the function containing the defer statement returns, the defered function calls are popped and executed one by one, in the scope that the defer statement was inside in the first place. Defer statements look like function calls, but are not executed until they are popped.

What is defer in Golang?

In Golang, the defer keyword is used to delay the execution of a function or a statement until the nearby function returns. In simple words, defer will move the execution of the statement to the very end inside a function.


2 Answers

To emulate defer fmt.Println(*a, i) example, you could use 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") 

Output

counting done 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 

It is easy to emulate the mutex case:

def some_function(lock=Lock()):     with lock:         # whatever 
like image 150
jfs Avatar answered Sep 23 '22 08:09

jfs


Python's with statement serves a similar purpose to Go's defer.

The similar code in Python is:

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. 
like image 22
Bayta Darell Avatar answered Sep 21 '22 08:09

Bayta Darell