The __enter__
method is never given any arguments, so beyond self
your signature should not have any other.
You should move those arguments to the __init__
method instead:
class FooBar(object):
def __init__(self, param1, param2):
# do something here ...
def __enter__(self):
# something else, perhaps return self
Creating an instance of FooBar()
is a separate step. with
calls __enter__
on the result of your mymod.FooBar("hello", 123)
expression, the expression itself is not translated to an __enter__
call.
If it was, you couldn't also use it like this, but you can:
cm = mymod.FooBar("hello", 123)
with cm as x:
# do something here with x, which is the return value of cm.__enter__()
Note that x
is assigned whatever cm.__enter__()
returned; you can return self
from __enter__
or you can return something entirely different.
The expected methods __enter__
and __exit__
are documented in the With Statement Context Managers section of the Python Data model documentation:
object.__enter__(self)
Enter the runtime context related to this object. The with
statement will bind this method’s return value to the target(s) specified in the as
clause of the statement, if any.
as well as in the Content Manager Types section of the Built-In Types documentation:
contextmanager.__enter__()
Enter the runtime context and return either this object or another object related to the runtime context. The value returned by this method is bound to the identifier in the as
clause of with
statements using this context manager.
An example of a context manager that returns itself is a file object. File objects return themselves from __enter__()
to allow open()
to be used as the context expression in a with
statement.
If you are interested in the exact interactions, see the original proposal: PEP 343 -- The "with" Statement; from the specification section you can see what with EXPR as VAR: BLOCK
statement does under the hood:
mgr = (EXPR)
exit = type(mgr).__exit__ # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
try:
VAR = value # Only if "as VAR" is present
BLOCK
except:
# The exceptional case is handled here
exc = False
if not exit(mgr, *sys.exc_info()):
raise
# The exception is swallowed if exit() returns true
finally:
# The normal and non-local-goto cases are handled here
if exc:
exit(mgr, None, None, None)
Note the mgr = (EXPR)
part; in your case, mymod.FooBar("hello", 123)
is that part. Also note that (EXPR)
, __enter__
and __exit__
are not 'protected' by the try..except
here, exceptions raised in the expression or when entering or exiting are not handled by the context manager!