2007年07月10日

アイテムポーズのコピペ その2 modo 203

さて、アイテムのプロパティを一時的に保存して、それを他の構造に読み込むためには記録するための仕組みとしてファイルへの書き出しと読み込みを使うことにする。本来ならユーザー値を使いたいところなのだがあまり大量のデータを記録することが出来ないという事は前回書いた通りだ。

さて、ファイルの処理は以下の通りの手順で行う。

  1. ファイルを開く
  2. ファイルを処理する
  3. ファイルを閉じる

ファイルを開くって作業はワープロだろうがCGソフトだろうが日々やってる作業だけど、プログラム的にはどんな意味があるかって言うと、処理するファイルをプログラム中で扱えるようにするインターフェースを構築するって感じかな。それが出来たらプログラムはそのインターフェースに対して作業をすると、裏でOSが働いてファイルにデータを書き込んだり読み出したりしてくれるわけだ。この仕組みをPythonでは「ファイルオブジェクト」なんて呼び方をする。

例えばabc.txtという名前のファイルから1行読み込むには以下のようにする。

f = open("abc.txt","r")
s = f.readline( )
f.close( )

open( )がファイルを開くファンクションで、open( ファイル名 , モード )のような書式で使う。ファイル名は開くファイルを指定するためのものだ。モードの方は、このファイルに対して書き出しがしたいのか、読み込みたいのかといった事を指定するためのものだ。以下がその一覧だ。

オプション 内容
r 読み出し。ファイルが無いとエラーになる。
w 書き込み(ファイルがあっても上書きされ、無ければ新規に作成される)
a ファイルがあればその後ろに追加され、無ければ新規に作成される
r+ ファイルを読み書き両用として開く。ファイルが無ければエラーになる。
w+ ファイルを読み書き両用として開く。ファイルがあれば上書きされ、無ければ新規に作成される。
a+ ファイルがあればその後ろに追加され、無ければ新規に作成される。読み込みも可能。
U 異なる改行コードに対応する
b バイナリーモード

このopen()ファンクションの実行結果として得られるのがファイルオブジェクトで、変数fにセットされる。ファイルの処理は全てこのファイルオブジェクトを通して行う。例えばこの例のように1行読み込むにはf.readline()のように書く。このreadline()は普通のファンクションとはちょっと違って、ファイルオブジェクトに装備された仕組みのひとつだ。イメージとしてはファイルオブジェクトにくっついたコマンドボタンみたいなもので、ボタンを押すかわりに「f.readline()」のようにファイルオブジェクトにくっつけて書くことで起動できる。いわばオブジェクトの操作メニューみたいなもんだ。メニューであれば一覧してどんなものがあるか知りたくなるもんだけど、Pythonではdir()ファンクションを使うことでそれをすることも可能だ。

例えば変数fにファイルオブジェクトがセットされている状態で、

dir(f)

とすれば、このオブジェクトにくっついているメソッドを含む属性が一覧できる。以下がその結果だ。

['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'close', 'closed', 'encoding', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines']

こんな感じでファイルオブジェクトにはreadlineがくっついているのが確認できる。ファイル操作はこのようにファイルオブジェクトに用意されたメソッドを操作して行うわけだ。

ファイルの操作が終わったらclose()メソッドでファイルを閉じる。これでファイルとプログラムの縁が切れるわけだな。

今回は単純にファイルを作ってそこにデータを書き込むことと、書き込んだデータを順に読み出すことが出来ればいいので、メソッドとしてはあとは書き出しのためのwrite()メソッドを知っていれば充分かな。下のプログラムは1行分のテキストを書き出すプログラムだ。文字列の後ろに付いている”\n”は改行を表す文字列で、これを入れておかないと、改行無しで書き込んだデータが繋がっていってしまう。readline()で読み込む時に行が切れていないと困るので、必ず入れておく。

f = open("abc.txt","w")
f.write("このテキストが書き込まれる\n" )
f.close( )

余談だけど、ファイルオブジェクトにはテキストファイルを一度に読み込んでリストとして返すreadlines( )メソッドや、シーケンスデータを一挙に書き出すwritelines( )なんていうメソッドも存在するよ。これを使えば下記のようにfor文と組み合わせて全ての行を処理するようなプログラムを作ることも出来るよ。ただしwritelines()を使う時は改行コードを自分で付けないとならないので注意が必要だ(改行を付けないと全部が1行に繋がっちゃうよ)。

f = open("abc.txt","r")
for line in f.readlines():
    print line
f.close( )

さて、これでデータを書き出して保存して読み込んで戻すことは可能になった訳だけど、そのファイルをどこに置くかって問題が発生する。WindowsとMacではファイルシステムが若干異なっているので、両者共通の方式でフルパス指定する事は出来ない。そんな時に役に立つのがplatformserviceのpath.path アートリビュートで、これに対してクエリすれば、今使っているmodoに設定されているユーザーフォルダやテンポラリフォルダのパスを教えてくれる。今回は一時的にデータを記憶するためのファイルなのでテンポラリフォルダに置くのがいいだろう。そこで、データを格納するファイルを「item.tmp」とすると、パスを含んだファイル名はこのようにすれば得られる。

 path=lx.eval("query platformservice path.path ? temp")
 file=path+"/item.tmp" 

例えば現在選択されているアイテムの位置をファイルに書き出す場合はこんなプログラムになる。アイテムをひとつ選択してこのプログラムを実行すれば、データが書き出されるはずだ。

#python
import lx
path=lx.eval("query platformservice path.path ? temp")
file=path+"/item.tmp"
f=open(file,"w")
px=lx.eval("item.channel locator$pos.X ?")
py=lx.eval("item.channel locator$pos.Y ?")
pz=lx.eval("item.channel locator$pos.Z ?")
f.write("%s,%s,%s\n" % (px,py,pz))
f.close()

ちゃんと書き出せたか確認したければ、コマンドラインから「query platformservice path.path ? temp」を打ち込んで自分のmodoのテンポラリフォルダがどこにあるかを確認して、その中を探せばitem.tmpが見つかるはずなので、それをテキストエディタで開いてみればいい。

それではまた次回。

スクリプトまとめページ( Down Load はこちらから)  

カテゴリー別ページ

modo操作メモ



take_z_ultima at 12:31│Comments(0)TrackBack(0)modo | CG

トラックバックURL

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 

Archives