Python備忘録1 リスト・辞書の展開

     最近はほとんどPythonでMaya用スクリプトを書いてるためすっかりMELの書式を忘れてしまったEskeでございます。ifのあと()いれるの面倒臭~、構文の最後に;入れるの面倒くせぇ~・・・でもswitchは欲しかった

     そんな中で、色々便利技(と言うほどでもないが)に気づいた事をメモっときます。

    ■リスト・辞書の展開

     これはPythonの基礎っポイんですが、よく不安になるんで備忘録のために書いときます。
     Pythonではリストを格納した変数の頭に*、辞書を格納した変数の頭に**をつけると、それぞれを展開して渡してくれます。
     その前に展開ってなに?って話なんで、例をあげます。
    例)
     たとえばMayaでtranslateに値をセットする場合書式は
    import maya.cmds
    mc.setAttr( 'pCube1.translate', 1, 2, 3 )
    と言うふうに、オブジェクト名、値X、値Y、値Zと入れます。
     ところで、頂点座標なんかを取得する場合、返ってくる値はリストです。
    pos = mc.pointPosition( 'pCube1.vtx[0]', w=True )
    # Result: [-0.5, -0.5, 0.5] # 

    んで、このリストの結果を使ってsetAttrする場合、わざわざこのリストの要素1個1個を個別に渡す必要があります。
    import maya.cmds
    pos = mc.pointPosition( 'pCube1.vtx[0]', w=True )
    mc.setAttr( 'pCube1.translate', pos[0], pos[1], pos[2] )
    メンドクサ!

     なんでposの中に入ってる値が3つからなるリストだってわかりきってるのに、わざわざ3回も書かなアカンの!
     一回くらいならいいですけど、これを繰り返してるとボディブローのようにジワジワと面倒くささが腹に染みてきます(ボディブロー食らったことないけど)
     で、MELの場合はこんな仕様に怒りを覚えつつ受け入れるしかなかったのですが、Python場合前述したリストの展開を使うと・・・
    import maya.cmds
    pos = mc.pointPosition( 'pCube1.vtx[0]', w=True )
    mc.setAttr( 'pCube1.translate', *pos )
    ネ申キターーーーー
     実にシンプルです。コードも短くなってスッキリ!素晴らしいです。
     strオブジェクトのメソッド".join"はリストを渡すのに、os.pathの”.join"は個別に渡さなくてはイケなくて殺意の波動に目覚めそうになっていたアナタもこれで満足なはず(笑)

     辞書も頭に**をつけてやることによって同様の事ができます。
     でもMELは辞書をサポートしてないから、辞書を展開して渡す機会なんてなくね?と思われるかもしれませんね。
     ところが! もの凄く身近なところで辞書型を使っていたのです!! いや、身近どころかPythonでMayaを動かすならほとんど辞書だらけなんですよ!!! それは・・・
    ビルドインコマンドに引数を渡す時です( ̄^ ̄)=э
    え、知ってるって? グフ、それはすいません、スイマセン、あ、石は投げないで

     知ってる方も多いと思いますが、pythonからmayaのコマンドにアクセスするとき、引数指定は辞書型で定義されています。
    import maya.cmds as mc
    mc.ls( sl=True, dag=True, type=['transform'] )
    このlsに渡してる引数は全部辞書で指定しています。なので前述した辞書型オブジェクトの展開を使ってこういうふうに指定することができます。
    import maya.cmds as mc
    options = {'sl':True, 'dag':True, 'type':['transform']}
    mc.ls( **options )

    そうです、つまり
    動的にフラグを変更したい時にevalをワザワザ使わなくてもいいようになります!
    コマンドをワザワザ文字列にするために面倒な思いをしていたのもこれでおさらばできます!なんと言う素晴らしい仕様・・・
     もちろんPythonの仕様上、決め打ちのフラグと展開された辞書の混合も可能です。
    import maya.cmds as mc
    options = {'sl':True, 'dag':True}
    mc.ls( type=['transform'], **options )


     こんなウサン臭いのも作成できます。(これが構文的にいいのかどうかは別問題として)
    import maya.cmds as mc
    getRelation = {
        'relation':[ mc.listRelatives, {'c':True, 'pa':True} ],
        'connection':[ mc.listConnections, {'s':True, 'd':False, 'p':True, 'c':True} ]
    }
    nodes = mc.ls( sl=True )
    # 子供を取得
    getRelation['relation'][0]( nodes, **getRelation['relation'][1] )
    
    # コネクションを取得
    getRelation['connection'][0]( nodes, **getRelation['connection'][1] )
    


     思ったより長くなってしまった。今回はこれでメモ終了
    スポンサーサイト
    プロフィール

    Eske

    Author:Eske
    萌えイラストレーターを目指す3DCGイラストレーター。
    現在ポケモンカードゲーム、ガンダムトライエイジ、ガンダムコンクエスト、妖怪ウォッチとりつきカードゲームなどで3DCGを使用したイラストレーターとして参加中。

    主にここでは日々気づいたメモなんかを残してます。
    イラストのお仕事も受け付けております。ココからアクセスできますので、お気軽にご相談下さい。

    最新記事
    最新コメント
    カテゴリ
    最新トラックバック
    月別アーカイブ
    検索フォーム
    リンク
    QRコード
    QR