Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Yeah, Python has "context managers" that let you do the same thing. Here's the Python equivalent:

    with open("text.txt") as inf:
        print(inf.read())
User defined classes that implement special methods __enter__() and __exit__() can be used as context managers. More info: http://www.python.org/dev/peps/pep-0343/

For just file output/input Scheme has the "with-output-to-file" and "with-input-from-file" macros which redirect output and input to a given file. I vaguely remember Common Lisp having a similar thing, but I can't remember the name off hand.



Common Lisp has with-open-file for reading and writing files. It works pretty much the same way as everything else in this thread, so I won't post example code, but you can see some here:

http://www.lispworks.com/documentation/HyperSpec/Body/m_w_op...


I immediately thought of Python's context managers when I read this. What the article appeared to describe, which shouldn't be lost on any programmer, is "do stuff then clean up after yourself".


I often use:

  for line in open("name.txt"):
      print line # Or do something else with it.


Me too when I'm lazy but we shouldn't; it happens to work fine on CPython but on implementations use garbage collection instead of reference counting (e.g. Jython) it leaks file handlers. The "with" statement is the right cross-platform way to handle resources.


I'd imagine it's an implementation bug. Once the iterator finishes, the file should be closed and the file handler freed.


Perhaps in this case - but how about a case where you partially iterate over the file, but then the file object goes out of scope? CPython would close (and free) that immediately, but other implementations probably wouldn't.


While editing the answer to masklinn comment, this case came to me. You both are, of course, right. There is no reliable way to close the file from the for iterator.

:-/


> I'd imagine it's an implementation bug.

No, it's a code bug.

> Once the iterator finishes, the file should be closed and the file handler freed.

There is no reason for that to happen, let alone for that to happen deterministically.


Indeed. In generational garbage collectors, the file object may remain until the collector decides to collect it. But isn't the file object also raising a StopIteration error? Shouldn't it at least close itself then?


You can always fp.seek(0) and iterate again. Iteration and file openness are separate concepts, and any API worth its salt (e.g. the python file api) keeps it that way.


If you've opened that file in the right mode, you can conceivably append to it once you reach its end. Even in read only mode, I imagine you may conceivably seek back for further reading?


That wouldn't be the idiomatic "for line in file" loop.


As far as iteration goes, there is no difference between

    for line in open(somepath):
        # stuff
and

    f = open(somepath)
    for line in f:
        # stuff
and the second case would be outright broken if the file just decided to close itself when it stops iterating (as others noted, the developer may now want to append new content, or use file.seek and fly around the file's content).

Not to mention a major issue: `break`. The iterator gets no mention of breaks and the iteration is not terminated at this point (as far as the iterator is concerned, that is) so adding a `break` to your iteration (to stop it early because you've found the data/line you needed in a linear search) would suddenly start leaking file handlers where those were collected beforehand... not good.


For that to work as it does in CPython, the file would have to know it has no name reference attached to it and that its scope is limited to the iteration and that it can close the file when the iteration ends. I'd love to have this idiom supported under other implementations - it's beautiful.


> For that to work as it does in CPython, the file would have to know it has no name reference attached to it and that its scope is limited to the iteration and that it can close the file when the iteration ends.

Which will never happen and really has nothing to do with iteration (or the file object itself)

> I'd love to have this idiom supported under other implementations - it's beautiful.

I disagree on its beauty, but beyond that I can assure you it's never going to be a property of python-the-language.


On the other hand, the Ruby equivalent is

def in_context(*args) setup_context yield if block_given? ensure teardown_context end

I guess you could build a special class, but why?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: