添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Let's say we want to implement an equivalent of the PHP's file_get_content .

What is the best practice? (elegant and reliable)

Here are some proposition, are they correct?

using with statement:

def file_get_contents(filename):
    with file(filename) as f:
        s = f.read()
    return s

is using standard open() safe?

def file_get_contents(filename):
    return open(filename).read()

What happens to file descriptor in either solution?

In the current implementation of CPython, both will generally immediately close the file. However, Python the language makes no such guarantee for the second one - the file will eventually be closed, but the finaliser may not be called until the next gc cycle. Implementations like Jython and IronPython will work like this, so it's good practice to explicitely close your files.

I'd say using the first solution is the best practice, though open is generally preferred to file. Note that you can shorten it a little though if you prefer the brevity of the second example:

def file_get_contents(filename):
    with open(filename) as f:
        return f.read()

The __exit__ part of the context manager will execute when you leave the body for any reason, including exceptions and returning from the function - there's no need to use an intermediate variable.

from PEP 343: python.org/dev/peps/pep-0343 Note that we're not guaranteeing that the finally-clause is executed immediately after the generator object becomes unused, even though this is how it will work in CPython. This is similar to auto-closing files: while a reference-counting implementation like CPython deallocates an object as soon as the last reference to it goes away, implementations that use other GC algorithms do not make the same guarantee. This applies to Jython, IronPython, and probably to Python running on Parrot. – kriss Sep 16, 2009 at 14:40 @kriss: Note that that doesn't contradict the statement about running __exit__ when leaving the body - it just details what happens if you don't exit the body by having a generator suspended within the context manager, and how python will force it to leave by raising an exception. – Brian Sep 16, 2009 at 15:18 This misses the point of using with - this code has the same weakness as explicit new/delete in C++ code - in the event of any intervening exception before the cleanup code, the cleanup just doesn't happen. On earlier Python's, one could wrap this example in try/catch/finally, but the cool kids are all using with. – PaulMcG Sep 16, 2009 at 12:04 This misses the point of the question on reliability. It adds unwanted features (check on file existence), and is not particularly elegant (importing os and code length). – vaab Sep 16, 2009 at 15:50

Using the with statement is actually the nicest way to be sure that the file is really closed.

Depending on the garbage collector behavior for this task might work, but in this case, there is a nice way to be sure in all cases, so...

Not quite. On CPython, the file is closed as soon as the file descriptor goes out of scope - certainly by the time the function returns. (I checked the Python source, as this point came up elsewhere recently.) On IronPython and Jython, the file will get closed when the file object is garbage collected, but there's no guarantees as to when that'll be. – Vinay Sajip Sep 16, 2009 at 10:25 @Hank Gay: if you don't with there are no guarantees -- the OS file descriptor may be left open. – S.Lott Sep 16, 2009 at 11:14
>>> ''.join(open('htdocs/config.php', 'r').readlines())
"This is the first line of the file.\nSecond line of the file"

Read more here http://docs.python.org/py3k/tutorial/inputoutput.html

Be careful when posting copy and paste boilerplate/verbatim answers to multiple questions, these tend to be flagged as "spammy" by the community. If you're doing this then it usually means the questions are duplicates so flag them as such instead. stackoverflow.com/questions/1433577 – Kev Jun 7, 2012 at 21:55

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.