what happens when we exit a code block where a file is opened using the keyword with?
what happens when we exit a code block where a file is opened using the keyword with? Ne90'dan bulabilirsiniz
If you're opening a file using the 'with' statement, do you still need to close the file object?
The ‘with‘ statement clarifies code that previously would use try...finally blocks to ensure that clean-up code is executed. In this section, I’ll discuss the statement as it will commonly be used. In the next section, I’ll examine the implementation details and show how to write objects for use with this statement.
The ‘with‘ statement is a control-flow structure whose basic structure is:
with expression [as variable]: with-block
The expression is evaluated, and it should result in an object that supports the context management protocol (that is, has enter() and exit() methods).
Yazı kaynağı : stackoverflow.com
Python close() File – Open and Close Files Properly
We can see that appending to the file from f2
isn't reflected in f3
.
Coding like this could also potentially corrupt a file, preventing it from being read or used again in the future. This example is simple, but if you were writing a script that appended extra information to a long file filled with valuable customer data or data that's taken months to web scrape, file corruption would become a costly problem.
To fix this example, we would need to make sure to close the file after writing before trying to read it again:
Yazı kaynağı : www.learndatasci.com
PEP 343 – The “with” Statement | peps.python.org
Specification: The ‘with’ Statement
A new statement is proposed with the syntax:
Here, ‘with’ and ‘as’ are new keywords; EXPR
is an arbitrary
expression (but not an expression-list) and VAR
is a single
assignment target. It can not be a comma-separated sequence of
variables, but it can be a parenthesized comma-separated
sequence of variables. (This restriction makes a future extension
possible of the syntax to have multiple comma-separated resources,
each with its own optional as-clause.)
The “as VAR” part is optional.
The translation of the above statement is:
Here, the lowercase variables (mgr, exit, value, exc) are internal variables and not accessible to the user; they will most likely be implemented as special registers or stack positions.
The details of the above translation are intended to prescribe the
exact semantics. If either of the relevant methods are not found
as expected, the interpreter will raise AttributeError
, in the
order that they are tried (__exit__
, __enter__
).
Similarly, if any of the calls raises an exception, the effect is
exactly as it would be in the above code. Finally, if BLOCK
contains a break, continue or return statement, the __exit__()
method is called with three None arguments just as if BLOCK
completed normally. (I.e. these “pseudo-exceptions” are not seen
as exceptions by __exit__()
.)
If the “as VAR” part of the syntax is omitted, the “VAR =” part of
the translation is omitted (but mgr.__enter__()
is still called).
The calling convention for mgr.__exit__()
is as follows. If the
finally-suite was reached through normal completion of BLOCK
or
through a non-local goto (a break, continue or return statement in
BLOCK
), mgr.__exit__()
is called with three None
arguments. If
the finally-suite was reached through an exception raised in
BLOCK
, mgr.__exit__()
is called with three arguments representing
the exception type, value, and traceback.
IMPORTANT: if mgr.__exit__()
returns a “true” value, the exception
is “swallowed”. That is, if it returns “true”, execution
continues at the next statement after the with-statement, even if
an exception happened inside the with-statement. However, if the
with-statement was left via a non-local goto (break, continue or
return), this non-local return is resumed when mgr.__exit__()
returns regardless of the return value. The motivation for this
detail is to make it possible for mgr.__exit__()
to swallow
exceptions, without making it too easy (since the default return
value, None
, is false and this causes the exception to be
re-raised). The main use case for swallowing exceptions is to
make it possible to write the @contextmanager
decorator so
that a try/except block in a decorated generator behaves exactly
as if the body of the generator were expanded in-line at the place
of the with-statement.
The motivation for passing the exception details to __exit__()
, as
opposed to the argument-less __exit__()
from PEP 310, was given by
the transactional()
use case, example 3 below. The template in
that example must commit or roll back the transaction depending on
whether an exception occurred or not. Rather than just having a
boolean flag indicating whether an exception occurred, we pass the
complete exception information, for the benefit of an
exception-logging facility for example. Relying on sys.exc_info()
to get at the exception information was rejected; sys.exc_info()
has very complex semantics and it is perfectly possible that it
returns the exception information for an exception that was caught
ages ago. It was also proposed to add an additional boolean to
distinguish between reaching the end of BLOCK
and a non-local
goto. This was rejected as too complex and unnecessary; a
non-local goto should be considered unexceptional for the purposes
of a database transaction roll-back decision.
To facilitate chaining of contexts in Python code that directly
manipulates context managers, __exit__()
methods should not
re-raise the error that is passed in to them. It is always the
responsibility of the caller of the __exit__()
method to do any
reraising in that case.
That way, if the caller needs to tell whether the __exit__()
invocation failed (as opposed to successfully cleaning up before
propagating the original error), it can do so.
If __exit__()
returns without an error, this can then be
interpreted as success of the __exit__()
method itself (regardless
of whether or not the original error is to be propagated or
suppressed).
However, if __exit__()
propagates an exception to its caller, this
means that __exit__()
itself has failed. Thus, __exit__()
methods should avoid raising errors unless they have actually
failed. (And allowing the original error to proceed isn’t a
failure.)
Yazı kaynağı : peps.python.org
Yorumların yanıtı sitenin aşağı kısmında
Ali : bilmiyorum, keşke arkadaşlar yorumlarda yanıt versinler.