I know context managers and decorators are two completely unrelated concepts in Python, but both can be used to achieve the same goal. It can be sometimes confusing which one is the best practice to use. In Maya, if you want a list of actions to be grouped as a single element of the undo queue, you need to open and close the chunk. It is quite risky because if an exception is raised while the chunk is open, it can break the undo queue entirely.
Let's say I want to execute while the undo chunk is open the following code:
def do_stuff():
print("I do stuff...")
One way is to write:
cmds.undoInfo(openChunk=True)
try:
do_stuff()
finally:
cmds.undoInfo(closeChunk=True)
It is obviously a one-off solution and is not very practical. I know I can automatize it as a decorator as such:
def open_undo_chunk(func):
def wrapper():
cmds.undoInfo(openChunk=True)
print("chunck opened")
func()
cmds.undoInfo(closeChunk=True)
print("chunck closed")
return wrapper
@open_undo_chunk
def do_stuff():
print("I do stuff...")
do_stuff()
But another way to do this would be to use the context manager.
class Open_undo_chunk():
def __enter__(self):
cmds.undoInfo(openChunk=True)
print("chunck opened")
return
def __exit__(self, exec_type, exec_val, traceback):
cmds.undoInfo(closeChunk=True)
print("chunck closed")
with Open_undo_chunk():
do_stuff()
Which one is the best practice and why in this context?