James Bell wrote:
I'm attempting to learn how to use the "with....as" statement in python.

I've read the documentation and also a few tutorials but I still cannot
understand the concept. or how this is normally used. Can someone please
write an example or 2 of simple ways to use the "with statement".

I understand in java the try...catch...finally block so maybe someone can
point out the relationship between them.

Java's try...catch...finally is called try...except...finally in Python.

In simple terms, a with-block uses a "context manager" to automatically wrap code in a try...finally block so as to ensure that cleanup code runs automatically even in the event of an error.

So that's the basic principle. Instead of having to write this *every time* you need to process some stuff:

    initialisation code
    try:
        process stuff
    finally:
        clean up code

you can write the initialisation and cleanup code *once* in a context manager, then do:

    with context manager:
        process stuff

and have both the initialisation and cleanup code automatically handled by the context manager.

So what's a context manager? I'll tell you what they *aren't* -- they are NOT a special type or class. Any class can be a context manager if it obeys the right protocol:

* the class must have a special method called __enter__

* the class must have a special method called __exit__

Of course, both __enter__ and __exit__ have to get the details right: they have to take the right number of arguments, and do the right thing.

Other than than, any class or type can be context managers, and Python comes with a few built in. The most important are file objects: any file object is also a context manager, so you can say:

with open("myfile.txt") as f:
    process(f)

and the file object will be automatically closed when the with block is done, even if an error occurs.

Some other examples (from memory) include decimal Context objects, unittest test features, and probably quite a few others.

How do you use a context manager? Easy -- you just call it using "with".

py> with open("rubbish.txt", "w") as fp:
...     fp.write("starting to write...")
...     fp.write(99)  # oops!
...
20
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
TypeError: must be str, not int
py>
py> open("rubbish.txt").read()
'starting to write...'


Opening the file a second time (this time *without* the with statement) shows that despite the error, the text was saved to disk and the file closed without any additional effort.


So how do you write your own context manager?

Naturally you can just define a class and give it the appropriate __enter__ and __exit__ methods. But there's an easy way. Python has a library to help you write context manager objects. Here's a toy example:

import contextlib
@contextlib.contextmanager
def my_manager(obj):
    print("called manager with argument %s" % obj)
    print("setting up manager...")
    try:
        value = ['anything', 'you', 'like', str(obj)]
        yield value
    finally:
        print("cleanup code running...")


Now I can use my_manager in a with-statement:


py> with my_manager(42) as data:
...     print("processing data")
...     data.sort()
...     print(data)
...
called manager with argument 42
setting up manager...
processing data
['42', 'anything', 'like', 'you']
cleanup code running...



--
Steven
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to