> You can move the resource allocation from __init__ to __enter__, but now you split your initialization code over 2 constructors
After giving it some thought, I've come up with a better example which more closely maps to C++ RAII constructs, which shows that you don't need to split anything. Consider:
class Shadow(object):
def __init__(self):
# Initialization code
@classmethod
def __enter__(cls, *args, **kwargs):
return cls(*args, **kwargs)
def __exit__(self, *args, **kwargs):
# De-initialize
`__enter__` becomes three lines of boilerplate, which you could abstract out into an inheritable class, should you so desire.As for "In C++ you write", it's the same as saying "in Python you write __enter__ and __exit__", but instead of instantiating via `std::unique_ptr` you use `with`.
Or, in C++ you write
and you never have to worry again.