Raymond Hettinger surprised quite a few people when he showed slides 36 and 37. https://speakerdeck.com/pyconslides/transforming-code-into-beautiful-idiomatic-python-by-raymond-hettinger -- Many people knew that the with statement could be used for opening files, but not these new things. Looking at python 3.3 docs on threading, only at the very bottom, section 16.2.8, is it even mentioned. From the lecture it was implied that using the 'with' operator was best practice.
ref:
__class__ is an attribute on the object that refers to the class from which the object was created. a. __class__ # Output: <class 'int'> b. __class__ # Output: <class 'float'> After simple data types, let's now understand the type function and __class__ attribute with the help of a user-defined class, Human .
A module in Python is a file (ending in .py ) that contains a set of definitions (variables and functions) that you can use when they are imported. Modules are considered as objects, just as everything else is in Python. Many methods can operate on modules.
The with statement in Python is used for resource management and exception handling. You'd most likely find it when working with file streams. For example, the statement ensures that the file stream process doesn't block other processes if an exception is raised, but terminates properly.
Python provides an easy way to manage resources: Context Managers. The with keyword is used. When it gets evaluated it should result in an object that performs context management. Context managers can be written using classes or functions(with decorators).
First, you don't ask if something is "withable", you ask if it's a "context manager".*
For example, in the docs you linked (which are from 3.1, not 3.3, by the way):
Currently,
Lock
,RLock
,Condition
,Semaphore
, andBoundedSemaphore
objects may be used aswith
statement context managers.
Meanwhile, if you want to search in the interactive interpreter, there are two obvious things to do:
if hasattr(x, '__exit__'):
print('x is a context manager')
try:
with x:
pass
except AttributeError:
pass
else:
print('x is a context manager')
Meanwhile:
help(open)
… makes no mention of it
Well, yeah, because open
isn't a context manager, it's a function that happens to return something that is a context manager. In 3.3, it can return a variety of different things depending on its parameters; in 2.7, it only returns one thing (a file
), but help
tells you exactly what it returns, and you can then use help
on whichever one is appropriate for your use case, or just look at its attributes, to see that it defines __exit__
.
At any rate, realistically, just remember that EAFTP applies to debugging and prototyping as well as to your final code. Try writing something with a with
statement first. If the expression you're trying to use as a context manager isn't one, you'll get an exception as soon as you try to run that code, which is pretty easy to debug. (It will generally be an AttributeError
about the lack of __exit__
, but even if it isn't, the fact that the traceback says it's from your with
line ought to tell you the problem.) And if you have an object that seems like it should be usable as a context manager, and isn't, you might want to consider filing a bug/bringing it up on the mailing lists/etc. (There are some classes in the stdlib that weren't context managers until someone complained.)
One last thing: If you're using a type that has a close
method, but isn't a context manager, just use contextlib.closing
around it:
with closing(legacy_file_like_object):
… or
with closing(legacy_file_like_object_producer()) as f:
In fact, you should really look at everything in contextlib
. @contextmanager
is very nifty, and nested
is handy if you need to backport 2.7/3.x code to 2.5, and, while closing
is trivial to write (if you have @contextmanager
), using the stdlib function makes your intentions clear.
* Actually, there was a bit of a debate about the naming, and it recurs every so often on the mailing lists. But the docs and help('with')
both give a nearly-precise definition, the "context manager" is the result of evaluating the "context expression". So, in with foo(bar) as baz, qux as quux:
, foo(bar)
and qux
are both context managers. (Or maybe in some way the two of them make up a single context manager.)
afaik any class/object that that implements __exit__
method (you may also need to implement __enter__
)
>>>dir(file)
#notice it includes __enter__ and __exit__
so
def supportsWith(some_ob):
if "__exit__" in dir(some_ob): #could justas easily used hasattr
return True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With