I have a context manager, subclass of a parent class/context-manager, that I'd like to terminate as soon as possible if some condition is met during the super().__init__
.
class CM:
def __init__(self, *args, **kwargs):
print('__init__')
super().__init__(*args, **kwargs)
self.condition_depending_on_super_init_result = True # set to true just to showcase the question
if self.condition_depending_on_super_init_result:
self.__exit__() # this has no impact: the lines after "with cm:" below are still executed!
self = None # why?
def __enter__(self):
print('__enter__')
def __exit__(self, *args):
print('__exit__')
def dosomething(self, x):
print(x)
cm = CM()
print('before with')
with cm: # here it should skip the block, not enter it, and not do the next lines
print('after with')
cm.dosomething('dosomething')
One reasonably obvious workaround is to raise an exception.
import logging # or whatever
class CMInitException(Exception):
"""
Exception raised by CM.__init__() if the superclass fails to initialize.
"""
pass
class CM:
def __init__(self, *args, **kwargs):
print('__init__')
super().__init__(*args, **kwargs)
self.condition_depending_on_super_init_result = True # set to true just to showcase the question
if self.condition_depending_on_super_init_result:
raise CMInitException("The moon over Redmond is not 3/4 full waxing")
def __enter__(self):
print('__enter__')
def __exit__(self, *args):
print('__exit__')
def dosomething(self, x):
print(x)
try:
cm = CM()
print('before with')
with cm:
print('after with')
cm.dosomething('dosomething')
except CMInitException as e:
logging.warning(e)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.