Symfoware

Symfowareについての考察blog

Thrift Pythonのコードを生成するときのオプションについて

久しぶりにThriftのページを見てみたら、いつの間にかWindows用のバイナリが
標準でビルドされるようになってました。

http://thrift.apache.org/download/
thrift-0.8.0.exe

また、thriftの定義体からPython用のコードを出力するときのオプションも
変更されているようでしたので、改めて使い方と指定したオプションにより
出力されるPythonのコードを違いと調べてみます。




使い方



ダウンロードのURLから「thrift-0.8.0.exe」をダウンロードしました。
http://thrift.apache.org/download/

また、出力されるコードの確認用に
http://svn.apache.org/repos/asf/thrift/trunk/tutorial/
ここから、「shared.thrift」と「tutorial.thrift」をダウンロードし、
thrift-0.8.0.exeと同じフォルダに保存します。


コマンドプロンプトを起動し、thrift-0.8.0.exeがあるフォルダへ移動。


thrift-0.8.0.exe --gen py tutorial.thrift



とすれば、gen-pyフォルダが作成され、その中にPythonのコードが出力されます。







出力オプション



引数を付けずに実行すると、指定できるオプションが表示されます。

thrift-0.8.0.exe



Pythonのコードを出力するときに指定可能なオプションは以下の通り。

オプション効果
new_styleGenerate new-style classes.
twistedGenerate Twisted-friendly RPC services.
utf8stringsEncode/decode strings using utf8 in the generated code.
slotsGenerate code using slots for instance members.
dynamicGenerate dynamic code, less code generated but slower.
dynbase=CLSDerive generated classes from class CLS instead of TBase.
dynexc=CLSDerive generated exceptions from CLS instead of TExceptionBase.


各々のオプションを指定し、出力されるコードを比較してみました。




new_style



オプション無しの出力

thrift-0.8.0.exe --gen py tutorial.thrift



new_styleオプションありの出力

thrift-0.8.0.exe --gen py:new_style tutorial.thrift



この2つは、出力されるPythonのコードのclassの指定方法に差があります。


オプション無しの場合は、class名の後に何もつきません。

  1. class Operation:



new_styleを指定したときは、明示的にobjectを継承するようになります。

  1. class Operation(object):









twisted



twistedオプションありの出力

thrift-0.8.0.exe --gen py:twisted tutorial.thrift




twistedを知らなかったのですが、
http://twistedmatrix.com/trac/


Twisted is an event-driven networking engine written in Python
and licensed under the open source


とのこと。今度触ってみます。


twistedオプションをつけると、Pythonのソースにこんなimportが追加され、
twistedを使用して通信を行うようになるみたいです。

  1. from zope.interface import Interface, implements
  2. from twisted.internet import defer
  3. from thrift.transport import TTwisted



また、クラスの宣言は(object)が付かない形式で生成されます。








utf8strings



utf8stringsオプションありの出力

thrift-0.8.0.exe --gen py:utf8strings tutorial.thrift




出力されるコードのttypes.pyで、文字列の扱いが異なります。

ソースの一部を抜粋すると、オプション無しの場合

  1. self.comment = iprot.readString();
  2. oprot.writeString(self.comment)




utf8stringsオプションありの場合

  1. self.comment = iprot.readString().decode('utf-8')
  2. oprot.writeString(self.comment.encode('utf-8'))




明示的にutf-8でエンコード、デコードが行われるようになります。

また、クラスの宣言は(object)が付かない形式で生成されます。







slots



slotsオプションありの出力

thrift-0.8.0.exe --gen py:slots tutorial.thrift




__slots__を使用したオブジェクトの生成が行われます。

__slots__、初めて聞いたのですが「__dict__」と「__weakref__」の自動生成を抑制し、
処理を高速化するテックニックのようです。

http://www.python.jp/doc/release/reference/datamodel.html#slots



具体例として、オプションを付けずに生成したソースの抜粋。


  1. def __repr__(self):
  2.     L = ['%s=%r' % (key, value)
  3.      for key, value in self.__dict__.iteritems()]
  4.     return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
  5. def __eq__(self, other):
  6.     return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
  7. def __ne__(self, other):
  8.     return not (self == other)
  9. class add_args:
  10. """
  11. Attributes:
  12. - num1
  13. - num2
  14. """




slotsオプションをつけた場合の同じ箇所。


  1. def __repr__(self):
  2.     L = ['%s=%r' % (key, getattr(self, key))
  3.      for key in self.__slots__]
  4.     return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
  5. def __eq__(self, other):
  6.     if not isinstance(other, self.__class__):
  7.      return False
  8.     for attr in self.__slots__:
  9.      my_val = getattr(self, attr)
  10.      other_val = getattr(other, attr)
  11.      if my_val != other_val:
  12.         return False
  13.     return True
  14. def __ne__(self, other):
  15.     return not (self == other)
  16. class add_args:
  17. """
  18. Attributes:
  19. - num1
  20. - num2
  21. """
  22. __slots__ = [
  23.     'num1',
  24.     'num2',
  25. ]




また、クラスの宣言は(object)が付かない形式で生成されます。





dynamic



dynamicオプションありの出力

thrift-0.8.0.exe --gen py:dynamic tutorial.thrift




TBinaryProtocol, TProtocolを使用せず、TBaseを使用した通信を行います。

オプション無しの場合


  1. from thrift.transport import TTransport
  2. from thrift.protocol import TBinaryProtocol, TProtocol




dynamicオプションありの場合


  1. from thrift.protocol.TBase import TBase, TExceptionBase









dynbase=CLS、dynexc=CLS



TBaseを継承した独自クラスを使用したい場合に指定するようですが、
今回は試していません。






複数のオプションを指定する場合



new_styleかつutf8stringsで出力したい場合は、カンマ区切りでオプションを指定します。


thrift-0.8.0.exe --gen py:new_style,utf8strings tutorial.thrift


関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2011/12/31(土) 10:40:30|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<Python logging 複数のロガー、ハンドラーの使用方法 | ホーム | Python logging 各種出力ハンドラーの使い方について>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/886-d0cf1d31
この記事にトラックバックする(FC2ブログユーザー)