Python __exit__ method missing

Some prerequisites: I work in a big bank, and I'm trying to reuse some Python modules that I cannot change, only import. I also do not have the ability to install any new utilities / functions, etc. (Running Python 2.6 on Linux).

I have this currently:

In my module:

from common.databaseHelper import BacktestingDatabaseHelper

class mfReportProcess(testingResource):
    def __init__(self):
        self.db = BacktestingDatabaseHelper.fromConfig('db_name')

One of the methods called in the testingResource class has the following:

 with self.db as handler:

which falls with this:

with self.db as handler:
AttributeError: 'BacktestingDatabaseHelper' object has no attribute '__exit__'

and, indeed, there is no method __exit__in the "BacktestingDatabaseHelper" class, a class that I cannot change.

, , - - , , ? - __exit__?

.

EDITED :

, - :

class myDB(BacktestingDatabaseHelper): 
    def __enter__(self): 
        self.db = fromConfig('db_name') 
    def __exit__(self): 
        self.db.close() 

:

self.db = myDB 

init , :

with self.db as handler:
TypeError: unbound method __enter__() must be called with myDB instance as first argument (got nothing instead)

, ?

+5
5

, BacktestingDatabaseHelper with. , testingResource BacktestingDatabaseHelper (, common.databaseHelper ).

+4

with , , with, .

, __enter__() __exit__(). , python AttributeError, __exit__.

+11

with, , BacktestingDatabaseHelper, __enter__() __exit__() .

, :

class myDB(BacktestingDatabaseHelper): 
    def __enter__(self): 
        return self
    def __exit__(self): 
        self.db.close()
    def fromConfig(self, name):
        x = super(myDB, self).fromConfig(name)
        assert isinstance(x, BacktestingDatabaseHelper)
        x.__class__ = myDB # not sure if that really works
[...]
self.db=myDB.fromConfig('tpbp')

, , __enter__. MySQLdb, , , . , - ...

+3

"" :

try:
    // Do something
finally:
    hander.__exit__()

, handler (, ). , , " -", .

- __exit__, with . , BacktestingDatabaseHelper, with.

, , with try ... finally , __exit__ . , ( , , BacktestingDatabaseHelper),

try:
    handler = self.db
    // do stuff
finally:
    handler.close()

Edit : Since you cannot change it, you should do something like @Daniel Roseman suggests a wrap BacktestingDatabaseHelper. Depending on how best to clean BacktestingDatabaseHelper(as stated above), you might write something like:

from contextlib import contextmanager

@contextmanager
def closing(thing):
    try:
        yield thing
    finally:
        thing.close()

and use it like:

class mfReportProcess(testingResource):
    def __init__(self):
        self.db = closing(BacktestingDatabaseHelper.fromConfig('db_name'))

(this is directly from the documentation ).

+2
source

You might want to try contextlib.contextmanagerdecorator to wrap your object so that it supports the context manager protocol.

+2
source

All Articles