How to check if an object is created with `with` statement?

前端 未结 6 1092
太阳男子
太阳男子 2021-01-02 02:15

I would like to ensure that the class is only instantiated within a \"with\" statement.

i.e. this one is ok:

with X() as x:
 ...

an

6条回答
  •  悲哀的现实
    2021-01-02 02:43

    OP's question was believed to be an XY problem, and the current chosen answer was indeed (too?) hacky.

    I don't really know the OP's original "X problem", but I'd assume the motivation was NOT literally about to "prevent x = X() ASSIGNMENT from working". Instead, it could be about to force the API user to always use x as a context manager, so that its __exit__(...) would always be triggered, which is the whole point of designing class X to be a context manager in the first place. At least, that was the reason brought me to this Q&A post.

    class Holder(object):
        def __init__(self, **kwargs):
            self._data = allocate(...)  # Say, it allocates 1 GB of memory, or a long-lived connection, etc.
        def do_something(self):
            do_something_with(self._data)
        def tear_down(self):
            unallocate(self._data)
    
        def __enter__(self):
            return self
        def __exit__(self, *args):
            self.tear_down()
    
    # This is desirable
    with Holder(...) as holder:
        holder.do_something()
    
    # This might not free the resource immediately, if at all
    def foo():
        holder = Holder(...)
        holder.do_something()
    

    That said, after learning all the conversations here, I ended up just leave my Holder class as-is, well, I just added one more docstring for my tear_down():

        def tear_down(self):
            """You are expect to call this eventually; or you can simply use this class as a context manager."""
            ...
    

    After all, we are all consenting adults here...

提交回复
热议问题