5 ms·
I'd go a little further and say context managers are underused on the whole. They're a great tool and aren't used often enough. ExitStack enables using contex
by xapata 6y ago
I'd go a little further and say context managers are underused on the whole. They're a great tool and aren't used often enough. ExitStack enables using context managers in more situations.
- toxik 6y agoProblem with context managers is that they add up indentation really, really fast. I guess TFA is at least a partial remedy to this though!
- redrum 6y agoTFA?
- drdrey 6y agoThe Fine Article, as posted by OP
- lunixbochs 6y agoYou can do multiple in a single with statement these days.
- BerislavLopac 6y agoThis is an often overlooked feature of context managers; to clarify, this is a perfectly normal example: with open("foo.txt") as foo_file, open("bar.txt") as bar_file, open("baz.txt", "w") as baz_file: baz_file.write(foo_file.read() + bar_file.read())
- lunixbochs 6y agoI think you can also do something like this if you want it to be readable with (open("foo.txt") as foo_file, open("bar.txt") as bar_file, open("baz.txt", "w") as baz_file): baz_file.write(foo_file.read() + bar_file.read())
- rndgermandude 6y agoC# has the using-statement + IDisposable which is similar context managers in python (except no __enter__). C#8 then allowed using-statements that do not require blocks, which then are disposed when leaving the current block. Pre C#8, you had to have a block, similar to how with-statement requires a block aka indentation using (var res = OpenSomeResource()) { res.doSomething(); // res.Dispose() implicitly called } Now you can have this (which is a bit like a go-style Defer but for blocks) using var res = OpenSomeResource(); res.doSomething(); // res.Dispose() implicitly called at end of current block Of course, you have to take the potentially longer lifetime into account. This way looks a lot like C++s RAII with constructors and destructors (except the destructor here is the IDisposible.Dispose implementation).
- arcticbull 6y agoIt's basically what all variables in Rust do, with customizable destruction by implementing the Drop trait.
- toxik 6y agoInteresting, I think that would make sense for Python. def do_thing(): with open('foo', 'r') as f with a_lock f.read() frobnicate() I guess the issue is that there is less of a clear idea of scope in Python, what does the above construct do at a module level? What does it do inside another with block? A lot of special rules that don't conveniently fit into something else unlike what I suppose C# has.