pythonjavawith-statementtry-with-resources

Difference between "with X as Y" in Python and try-with-resources in Java


I'm a bit new to Python still, and I got a question about the nuances of "with X as Y" in Python. It seems to be similar to a try-with-resources in Java, but I'm wondering what the differences are (so I don't make assumptions). So, what are the differences between the following two:

try (InputStream in = getInput()) {
    // Java -- Do stuff
}

and

with getInput() as source:
    # Python -- Do stuff

Solution

  • One difference in semantics is that with the following Java block:

    try (InputStream in = getInput()) {
        // Java -- Do stuff
    }
    ...
    InputStream in2 = getInput();
    assert(in2.getClass() == in.getClass());
    

    the variable in has the actual value returned by getInput(). But with Python, this is not necessarily the case:

    with getInput() as source:
        # Python -- Do stuff
    ...
    source2 = getInput()
    # Now source and source2 are not necessarily the same type
    

    Here, getInput() returns an object that has a method called __enter__(). The variable source is then assigned whatever value __enter()__ returns. It is a very common practice for __enter()__ to return self in order to avoid surprises, but it's not an actual requirement.