Reputation: 23
I'm required to use "with" on a method of an object and not on the object itself.
Here is what I've already tried:
class LSTM:
...
def run(self):
def __enter__(self):
do something
return self
def __exit__(self, type, value, tb):
return self
An example of I want to use the function in main:
lstm = LSTM(...)
with lstm.run():
...
The error I get:
AttributeError: __enter__
Upvotes: 1
Views: 67
Reputation: 8027
The context expression lstm.run()
of your with
statement does not evaluate to a context manager but to None
, since there is no return
statement in your run
method.
Cf. https://docs.python.org/3/reference/compound_stmts.html#the-with-statement
Upvotes: 0
Reputation: 50076
The object returned by your method must be a context manager. Write your method as a generator and apply the contextlib.contextmanager
decorator to automatically create the proper helper object:
from contextlib import contextmanager
class LSTM:
@contextmanager
def run(self):
# prepare
yield self
# clean up
The object created by the decorator uses anything before the yield
as __enter__
, and anything after it as __exit__
. Whatever is provided by yield
is available for use in the as
clause of the with statement. If an error terminates the context, it is raised at yield
.
Upvotes: 3
Reputation: 21275
When you write:
with soemthing:
Then the object soemthing
needs to have those __enter__
& __exit__
methods.
So for:
with lstm.run():
The object returned by lstm.run()
needs to have the __enter__
and __exit__
methods - the fact that lstm
has those methods is of no consequence.
What you should do will depend on what you're trying to achieve. But this:
with lstm:
Will call the __enter__
& __exit__
methods you have defined.
Upvotes: 1