class OracleConnected():
def __init__(self):
self.oracle_username = oracle_username[1]
self.oracle_password = oracle_password[1]
self.dsn = cx_Oracle.makedsn(hostname[1], port[1], sid[1])
def __enter__(self):
try:
print('Then this')
cx_Oracle.init_oracle_client(lib_dir=lib_dir)
self.connection = cx_Oracle.connect(user=self.oracle_username, password=self.oracle_password, dsn=self.dsn)
except Exception as e:
print(f'Error connecting to Oracle: \n{e}')
else:
yield self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
print('Finally do this')
#self.connection.close()
yield self.connection.close()
with OracleConnected() as connection:
print('It first do this')
cur = next(connection).cursor()
cur.execute("select *From payments where id = 324986093")
print(cur.fetchall())
If everything stays the same I got: It first do this Then this [(324986093, 391908893, 391908893, 1228, None, datetime.datetime(2023, 4, 24, 0, 0)]
Instead of yield self.connection.close() -> write just self.connection.close(): It first do this Then this [(324986093, 391908893, 391908893, 1228, None, datetime.datetime(2023, 4, 24, 0, 0)] Finally do this
So the question is, what is so special about yield that it gives me so much troubles?
P.S. Also, Instead of yield self.connection.close() -> return self.connection.close() I got desired answer: It first do this Then this [(324986093, 391908893, 391908893, 1228, None, datetime.datetime(2023, 4, 24, 0, 0)] Finally do this
P.S.S. On top of that, If I may ask - imagine that we solve this mystery. Another problem in the same code, if i get an error while connecting to server using self.connection and say it gives an error then i passed this error to exit and exit gives me an error as well - how to handle this situation also. So i did not pass it to exit?
I tried to read documentations, but nothing seemed to work. I just curious what are the causes of omitting exit
__enter__
and __exit__
shouldn't have yield
because then they'll return a generator and you have to iterate over the generator to completion for the method to finish executing.
You may be getting confused with @contextlib.contextmanager
which is a decorator that can be applied to a generator function to create a simple context manager without having to write a class with __enter__
and __exit__
.