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. }
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.
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.
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.
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")
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With