デコレーターを自作する方法!!

takkun
どうも!たっくんです。
最近、NetflixでDr.HOUSEを見てます∠( ゚д゚)/

Pythonでツールを作っている時に、ちょくちょくデコレーターを使う機会はあるかと思いますが、今回はデコレータを自作してみたいと思います!∠( ゚д゚)/

どんな時に使うの?(Maya向け)

  1. ツールの処理の前後に、undoInfoのopenChunk・closeChunkを入れたい
  2. ツールの処理が終わった時に、選択を戻したい

などなど、本来の処理の前後に追加したい処理がある場合にデコレーターを使うと大変便利です!(`・ω・´)ゞ

書式

デコレーターを作るときの書式は、以下のように関数の中に関数を作って行きます!

def デコレーターの名前(func):
	def wrapper(*args, **kwargs):
		関数の処理の前にやりたいコトを書く
		try:
			# デコレーターを付けた関数の実行
			return func(*args, **kwargs)
			
		except Exception, e:
			raise
			
		finally:
			関数の処理の後にやりたいコトを書く
	
	return wrapper

処理の前後に、openChunk・closeChunkを入れる

PySideなどのボタンをクリックしたら処理を実行・・・っというパターンはものすごく多くあると思いますが、直接関数を指定しちゃうと、Mayaコマンド1つ1つにヒストリーが残ってしまう場合があります・・・(´・ω・`)

大量に繰り返し処理をするツールでは、ヒストリーを一つにまとまるようにしないといけません。そんな時にデコレーターを作っておくと、以下の様に簡単に対応することができます!

from maya import cmds

def collectHistory(func):
	def wrapper(*args, **kwargs):
		cmds.undoInfo(ock=True)
		try:
			return func(*args, **kwargs)
			
		except Exception, e:
			raise
			
		finally:
			cmds.undoInfo(cck=True)
	
	return wrapper

@collectHistory
def callback():
	# なんらかのツール処理
	# callback()の実行前に、cmds.undoInfo(ock=True)が実行され
	# callback()の実行後に、cmds.undoInfo(cck=True)が実行される。
	pass

ツールの処理が終わった時に、選択を戻したい

Mayaコマンドのいくつかは、選択状況を変更してしまうものがありますね(´;ω;`)

ヒストリーと同様に、デコレーターを作っておくと、以下の様に簡単に対応することができます!

from maya import cmds

def preserveSelection(func):
	def wrapper(*args, **kwargs):
		selection = cmds.ls(sl=True)
		try:
			return func(*args, **kwargs)
			
		except Exception, e:
			raise
			
		finally:
			cmds.select(selection)
	
	return wrapper

@preserveSelection
def main():
	# なんらかのツール処理
	# main()の実行前に、cmds.undoInfo(ock=True)が実行され
	# main()の実行後に、cmds.undoInfo(cck=True)が実行される。
	pass