我知道上下文管理器和装饰器在Python中是两个完全不相关的概念,但它们都可以用于实现相同的目标。有时可能会混淆使用哪一种是最佳实践。 在Maya中,如果希望将动作列表分组为撤消队列的单个元素,则需要打开和关闭区块。这是相当危险的,因为如果在块打开时引发异常,它可能会完全中断撤消队列
假设我想在undo区块打开时执行以下代码:
def do_stuff():
print("I do stuff...")
一种方法是写:
cmds.undoInfo(openChunk=True)
try:
do_stuff()
finally:
cmds.undoInfo(closeChunk=True)
这显然是一个一次性的解决方案,不太实用。我知道作为一名装饰师,我可以将其自动化:
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()
但另一种方法是使用上下文管理器
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()
哪一个是最佳实践,为什么在这种情况下
我认为最佳实践通常归结为哪种风格最适合你。我并不特别认为这两种方法之间有明显的性能差异,但也许有人可以为我们做一些简单的基准测试
在对你的问题的非常主观的回答中,我个人更喜欢陈述。它表示您正在使用一个资源执行代码,该资源将在完成后自行处置。这通常也是执行内置上下文的方式,如打开文件时等
另外一个好处是,不需要定义要在with语句中运行的方法
但是,通过使用contextlib生成上下文,您可以节省一些精力:
Here's a thread with more information on the ^{} statement 。在上面,我实际上是在执行
yield None
,这意味着您不能对资源undoable()
返回执行任何操作。例如,如果您有一个文件指针或类似的东西,您可以yield <resource>
将其发送回调用上下文相关问题 更多 >
编程相关推荐