2013/03/25

if-inとか条件判定とかについて

ループまわすときによくみる「 for - in 」はmelのときから出会う機会も多かったですが、
そういえばPythonには「 if - in 」という書き方もあります。

今回は if - in な書き方と、if文の判定についてちょろっと書いてみたいと思います。



※今回も前提としてpymel.coreをpmとしてインポートしていることとします。

if-inはどんなときに使う書き方なのか、実は英文を読む感じでイメージを掴むことが出来ます。
↓こんな感じです。

if(→もしも)○○ in(→のなかに)△△:

読んで想像がつく通り、「△△のなかに、もし○○があったら」という内容になります。
実際どういう感じになるかでっちあげてみましょう。
たとえばこんな……

if 'pSphere3' in pm.selected():
    pm.select('pSphere3',deselect=1)

「選択中のオブジェクトの中に'pSphere3'が含まれていたら、'pSphere3'を選択から外す」ですね。selectコマンドの「deselect」フラグを有効にすることで、選択リストから外しています。
内容的にはif文に入れるまでもないので、あまり現実味は無い例ですが(^^;

ちなみに、Pythonでの条件判定には↓このような書き方も出来ます。

if not ○○ in △△:

ifのあとにnotが付きました。さっきは「もしあったら」という文でしたが、これで「もしなかったら」という内容になります。
melでは「== 0」とか「!=」とかそういった感じの書き方をしていましたが、よりなんというか自然言語に近い形で書くことが出来ます。読み下すときも理解し易いですね。こういう構文や書き方があるんだっていうことを知らなくても意味を掴むことが出来るんじゃないかという気がします。

if not 'pSphere3' in pm.selected():
    pm.select('pSphere3', add=1)

「もし選択中のオブジェクトに'pSphere3'が居なければ、追加選択」という例。
さっきのとまるっきり逆の内容ですね。
同様にして、こういうこともできます↓

if not pm.selected():
    pm.select('pSphere3')

「なにも選択していなければ~~」という感じですね。
もはやif-inとか関係なくなりました(w)
……ちなみにこれをmelで書くと、こんな感じ↓

if (size(`ls -sl`) == 0){
    ~~なんやかんや~~;
    }

ふと気を抜くと閉じ括弧や行末のセミコロンを忘れてしまいそうな今日この頃です(爆)


最後に、if-inを使ったささやかなネタを。
オブジェクトの中身を調べるときによく使う「dir()」ですが、
結果がずらりと出て来て見づらいですね。
正直、手軽に使えるから使ってはいるものの利便性に優れてるとは言いがたい感じです。
これを、if-inを使って微かに便利にしてみましょう。
まずは下調べとして、とりあえずdir()を実行してみます。

dir(pm)
# 結果: ['AbcExport',
 'AbcImport',
 'AmbiguityWarning',
 'Attribute',
 (中略)
 'wrinkleContext',
 'writeTake',
 'xform'] #

実行結果を眺めてみると、こいつはなんとなく [ ] で閉じられてますのでリストなんだなーって気づきます。

type(dir(pm))
# 結果: <type 'list'> # 

さもありなん。
if-inは「中にあったら」という判定が出来ますので、これで文字列検索が出来るんです。(というか上記の例もたまたまオブジェクト名を使っていたというだけで、文字列検索には違いなかったんですがw)
↓こんな感じになります。

for i in dir(pm):
    if 'export' in i:
        print i

例として、「export」という文字列で検索しています。
実行すると、pymel内の、'export'を含むアトリビュートが表示されます。
ちょっとだけ探し易くなりますね。
でも、pymel自体が非常に規模の大きなモジュールなので、検索ワードによっては大量すぎてあまり役に立たないかもしれませんw
たとえばpolyとか。。。

もし利用価値があるとお思いでしたら、悪ノリして関数化してみましょう。

def searchDir(obj,word):
    for i in dir(obj):
        if word in i:
            print i

一個目の引数に、中身を見たいオブジェクト。二個目の引数に、検索したい文字列を入れます。pythonの特徴として、インデント(字下げ)も構文上意味を持つことに注意ですb
さらに悪ノリを重ねて、dirと同様に検索結果がリストで返ってくるようにしませう。

def searchDir(obj,word):
    result = []
    for i in dir(obj):
        if word in i:
        result.append(i)
    return result

結果を返すように空のリスト「result」を用意して、if-in検索にひっかかったらappendメソッドをつかってリストに追加していってます。
appendはlistオブジェクトに用意されているメソッドで、与えられた引数をリストの後ろに追加して行ってくれます。これをforループに入れ、検索と併用することで、該当するものだけのリストを作成できる訳です。
最後に、そのリストをreturnして完成。
↓実行結果

searchDir(pm,'export')
# 結果: ['exportAll',
 'exportAnim',
 'exportAnimFromReference',
 'exportAsReference',
 'exportEdits',
 'exportSelected',
 'exportSelectedAnim',
 'exportSelectedAnimFromReference'] #

……という感じで if-in やら if not やらでした。if-inで文字検索というのが面白くて書いてみました。
コンビニで買い物しすぎたゴロウちゃんばりに顔を輝かせながらご活用いただければ幸いです。




■関連リンク

 「if ~in文」@No moer Retake 
http://nomoreretake.blogspot.jp/2012/05/if-in.html#!/2012/05/if-in.html 
▲おんなじ話題ですねww 

[Maya]はじめようPython part5「条件分岐1」  @たっきゅんのガ☆チンコ開発日記 
http://takkun.nyamuuuu.net/blog2/archives/3849 
[Maya]はじめようPython part6「条件分岐2」  @たっきゅんのガ☆チンコ開発日記 
http://takkun.nyamuuuu.net/blog2/archives/4090 

PEP 8
http://oldriver.org/python/pep-0008j.html
今回条件判定が出てきましたが、そう言った部分の書き方に付いて
いろいろ提案されているのが「PEP 8(ペップエイト)」。
一読の価値アリです(^^;

if 文 @Python2.7 Documentation » Python 言語リファレンス http://docs.python.jp/2.7/reference/compound_stmts.html#else 

dir( [object] )  @Python 標準ライブラリ>>2. 組み込み関数 
http://docs.python.jp/2.6/library/functions.html#dir

0 件のコメント:

コメントを投稿