-1

I am reading the Python Cookbook where the following is mentioned:

@contextmanager is really only used for writing self-contained context-management functions. If you have some object (e.g. a file, network connection, or lock) that needs to support the with statement, you still need to implement the __enter and __exit__ methods separately.

I can't quite understand this. Why can't we use a file object with a context-management function? Aren't functions decorated with @contextmanager equivalent to classes with __enter__ and __exit__ methods?

debashish
  • 1,374
  • 1
  • 19
  • 29

1 Answers1

2

Say you've got a class:

class DatabaseCursor(object):
    ...

and you want to add context manager functionality to it. Where would you put @contextmanager?

Not here:

@contextmanager
class DatabaseCursor(object):
    ...

Not here:

class DatabaseCursor(object):
    @contextmanager
    def __init__(self, ...):
        ...

Not here:

class DatabaseCursor(object):
    @contextmanager
    def __enter__(self):
        ...

Nowhere, really. @contextmanager doesn't help you add context manager functionality to existing classes. You can't even use @contextmanager-decorated functions as base classes, because the implementation doesn't actually create a class. If you want your file-like object or database cursor or network connection or other closeable resource to support use as a context manager, you have to implement __enter__ and __exit__ directly.

user2357112
  • 260,549
  • 28
  • 431
  • 505