简体   繁体   中英

Stop and terminate a context-manager before it begins (but after its __init__)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM