3 ms·
The issue I run into with Python's "with" is that you can't turn a class into a context manager without changing the calling scope. Suppose you have a class th
by MereInterest 4y ago
The issue I run into with Python's "with" is that you can't turn a class into a context manager without changing the calling scope. Suppose you have a class that initializes itself from a file, reads the entire file into memory, then accesses a few bytes here and there of the contents as needed. Somebody rightfully notices that the memory usage is way too high, so you instead open the file, and on demand seek to the location and read those few bytes.
The class now stores a file handle, which it should close. So the class should be changed to a context manager. So every call site needs to change from "x = MyFoo()" to "with MyFoo() as x:" in order to work correctly. With RAII, everything is already lifetimes, so the calling scope doesn't need to change if you add a destructor.
- sirwhinesalot 4y agoI commented something relating to this in another post, but since in Python/C# the resource and the container of the resource don't actually have tied lifetimes, you can do a different pattern where MyFoo() is a perfectly normal class, with a method within it that actually creates the context manager that loads the resource temporarily. If you do this, you can move and store MyFoo's around, but in order to access the resource without getting an exception to the face you need to use with, e.g. myfoo = MyFoo() # the actual resource is only acquired for the duration of the with block with myfoo.acquire(): myfoo.read_stuff() myfoos = [myfoo] # later with myfoos[0].acquire(): myfoo.read_stuff() Lifetimes are loose in GCed languages, so you shouldn't really think of some object's lifetime and the resources lifetime to be tied in any way, nor should APIs be designed with that assumption, even if the object represents the resource (confusing I know, specially since the languages themselves get this wrong).