前回はCPythonの講演とPyPyの講演を紹介しました。今回は、
Application:アプリケーション
Beyond Python Enhanced Generators:Python拡張ジェネレーターの先へ
動的にシーケンスを生成するものとしてジェネレーターがあります。本講演を紹介する前にPythonのジェネレーターについて簡単に紹介します。ジェネレーターは、
>>> def f():
... for i in range(3):
... yield i
>>> g = f()
>>> g.next()
0
>>> g.next()
1
>>> g.next()
2
>>> g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
forループの中でyield文が実行される毎に、next()
メソッドを実行することで、yield
された値を受け取れます。
ジェネレーターを任意の場所で終了させるときは、StopIteration
を発生させます。また、StopIteration
が発生します。
yield文は、
>>> def f():
... msg = yield "send me message"
... print msg
... yield
>>> g = f()
>>> g.next()
'send me message'
>>> g.send("Hello")
Hello
send()というメソッドでジェネレーター内へメッセージを送り、
本講演はWeightlessの開発者でもあるErik Groeneveld氏によって行われました。なお、
![Erik Groeneveld氏 Erik Groeneveld氏](/assets/images/news/report/01/europython2011/0004/thumb/TH300_001.jpg)
Weightless
Weightlessは、
- compose:コルーチンに分解するモジュール
- observable:オブザーバーパターンによるコンポーネントの設定モジュール
- gio:ソケットをコルーチンに接続するモジュール
Weightlessは、
![Weightlessモデル Weightlessモデル](/assets/images/news/report/01/europython2011/0004/thumb/TH800_002.png)
トランポリンモデル
一方でWeightlessのモデルと対比してトランポリンモデルも紹介されていました。筆者はトランポリン
![トランポリンモデル トランポリンモデル](/assets/images/news/report/01/europython2011/0004/thumb/TH800_003.png)
トランポリンモデルを表す次のサンプルコードが紹介されていました。
def demo_coroutine():
"""coroutine a la COBOL"""
def coroutine_a(n = 0):
while n < 10:
n = yield b, n + 1
print ">", n
def coroutine_b(n = 0):
while n < 10:
n = yield a, n + 1
print "<", n
a = coroutine_a()
b = coroutine_b()
a.next()
b.next()
g = (a, 0)
while True: # トランポリン
try:
g = g[0].send(g[1])
except:
break
>>> demo_coroutine()
> 0
< 1
> 2
< 3
...
coroutine_
はcoroutine_
を、coroutine_
はcoroutine_
を交互に呼び出します。この2つのジェネレーターを交互に呼び出す制御部にあたるのがwhileループの部分です。
while True: # トランポリン
try:
g = g[0].send(g[1])
except:
break
g = g[0].send(g[1])
はそれぞれのジェネレーターを交互に呼び出します。a.
を実行するとcoroutine_
ではn = 0
がセットされ、print “>”, n
が呼び出され、yield b, (n + 1)
によりcoroutine_
が一時停止します。呼び出し元ではg = (b, 1)
が返されて、b.
が実行されます。それからb.
を実行すると、yield a, (n + 1)
でcoroutine_
が一時停止して、g = (a, 2)
が返されます。
このように、
composeとPEP 380
composeモジュールを使ってジェネレータの処理をサブジェネレーターへ委譲します。Pythonのジェネレーターは、
実際に簡単なサンプルコードを書いてみます。
>>> def f():
... yield "Hello"
... msg = yield
... yield msg
>>> def g():
... yield f()
>>> _r = g()
>>> _r
<generator object g at 0x10078ca00>
>>> r = _r.next()
>>> r
<generator object f at 0x10078c550>
>>> r.next()
'Hello'
>>> r.next()
>>> r.send("World")
'World'
composeを使うと、
>>> from weightless.core import compose
>>> r = compose(g())
>>> r
<generator object _compose at 0x10078c910>
>>> r.next()
'Hello'
>>> r.next()
>>> r.send("World")
'World'
g()
というジェネレーターが返すサブジェネレーターを意識せずに操作できます。委譲の考え方から、g()
ジェネレーターが何をするかを知る必要はないのでcompose
がサブジェネレーターを適切に扱ってくれると、g()
ジェネレーターとの結合度が低くなります。
そしてcomposeはデコレーターとして使うこともできます。
@compose
def g():
yield f()
また、yield from
式を使って次のように記述できるようになる予定です。
def g():
yield from f()
composeはyield from
とよく似た概念であり、
5 Years Of Bad Ideas:過去5年間のバッドアイディア
日本でも人気のあるmitsuhikoことArmin Ronacher氏による講演です。氏はFlask,Jinja2,Sphinxといったフレームワークを開発しているPocooという開発チームのリーダーの1人でもあります。
本講演は、
なお、
![Armin Ronacher氏 Armin Ronacher氏](/assets/images/news/report/01/europython2011/0004/thumb/TH800_004.jpg)
Pythonとは何か?
Armin氏は、
- 美しいコード
- 統合性のある整然とした構文
- 関数を含め、
すべてがファーストクラス
また、
魔法について
@zedshaw氏による魔法についての見解を引用していました。少し調べてみましたが、
“And honestly, I only find this shit in web frameworks. WTF is up with Python people going ballistic when a web app uses magic? Bullshit.”
― Zed Shaw about Magic
また、
魔法の書
![普通の魔法 普通の魔法](/assets/images/news/report/01/europython2011/0004/thumb/TH800_005.png)
- フレームオブジェクト
sys._getframe()は、
コールスタックのフレームオブジェクトを返します。このフレームオブジェクトは、 インタープリターからの情報源になります。例えば、 実行中のソースの行番号は次のようにして取得できます。 >>> import sys >>> sys._getframe().f_
lineno 1また標準ライブラリにあるオブジェクトの情報を調べるinspectモジュールも、
内部的にsys._getframe()を使ってフレームオブジェクトを取得します。上述した行番号の取得は次のコードと同じです。 >>> import inspect >>> inspect.currentframe().f_
lineno 1- メタクラス
Pythonでメタクラスを使うには__
metaclass__ という特殊メソッドにtype()を継承したクラスを指定します。例えば、クラスの生成時に hello
というメソッドをもっているかをチェックするサンプルが次になります。class MyMetaclass(type): def __
new__ (cls, name, base, d): rv = super(MyMetaclass, cls).__new__ (cls, name, base, d) if not getattr(rv, "hello", None): raise NotImplementedError("Need to implement hello method") return rv class MyClass(object): __metaclass__ = MyMetaclass def hello(self): pass通常はこのようにメタクラスへtype()を継承したクラスを指定しますが、
この方法だとクラスに対して1つのメタクラスしか持てません。Pythonの class
文はtype()のシンタックスシュガーなので、__ metaclass__ はクラスでなくても、型オブジェクトを返すファクトリ関数を指定することもできます。 def implements(*interfaces): cls_
scope = sys._getframe(1).f_locals metacls = cls_scope .get('__metaclass__' ) metafactory = make_meta_ (metacls, interfaces) cls_factory scope ['__metaclass__' ] = metafactory class MyClass(object): implements(Interface1, Interface2)implements
関数内でクラスの__metaclass__ にファクトリ関数を指定するサンプルが紹介されていました。この方法だと、implements
は複数のインターフェイスを受け取れます。このサンプルの完全なソースはinterfaces.py にあるので、興味がある方はそちらを参照してください。 - AST
(抽象構文木) のハック 標準ライブラリにPythonのソースコードを抽象構文木というツリー状のデータに変換するastモジュールがあります。抽象構文木の演算子を書き換えるサンプルコードが紹介されていました。
>>> import ast >>> x = ast.parse("1 + 2", mode="eval") >>> x.body.op = ast.Sub() >>> eval(compile(x, "<string>", "eval")) -1
インタープリターとの魔大戦
![インタープリターとの魔大戦 インタープリターとの魔大戦](/assets/images/news/report/01/europython2011/0004/thumb/TH800_006.png)
- 変数名の取得
簡単にできそうで、
いざやろうとすると、 どうして良いのか悩むような課題です。 ガベージコレクタとのインターフェイスを提供するgcモジュールを使って変数名を取得しています。 import gc import sys def find_
names (obj): frame = sys._getframe(1) while frame is not None: frame.f_locals frame = frame.f_back result = set() for referrer in gc.get_referrers (obj): if isinstance(referrer, dict): for k, v in referrer.iteritems(): if v is obj: result.add(k) return tuple(result)>>> a = [] >>> b = a >>> find_
names (a) ('a', 'b')- 暗黙のself
Pythonの特徴の1つ、
明示的な self
を隠してしまうハックです。class User(ImplicitSelf): def __
init__ (username, password): self.username = username self.set_password (password) def set_password (password): self.hash = hashlib.sha1(password).hexdigest() def check_password (password): return hashlib.sha1(password).hexdigest() == self.hashメタクラスを使ってメソッドのバイトコードを書き換えているようです。
class ImplicitSelfType(type): def __
new__ (cls, name, bases, d): for key, value in d.iteritems(): if isinstance(value, FunctionType): implicit_self (value) return type.__new__ (cls, name, bases, d) def implicit_self (function): code = function.func_code bytecode , varnames, names = inject_self (code) function.func_code = CodeType(code.co_argcount + 1, code.co_nlocals + 1, code.co_stacksize , code.co_flags , bytecode, code.co_consts , names, varnames, code.co_filename , code.co_name , code.co_firstlineno , code.co_lnotab , code.co_freevars , code.co_cellvars )このサンプルの完全なソースはimplicitself.
py にあるので、興味がある方はそちらを参照してください。
lightning talks:ライトニングトークス
技術系イベントでは、
ライトニングトークスは、
![ライトニングトークス募集板 ライトニングトークス募集板](/assets/images/news/report/01/europython2011/0004/thumb/TH800_007.jpg)
blockdiag
小宮さんは、
![blockdiagの発表開始 blockdiagの発表開始](/assets/images/news/report/01/europython2011/0004/thumb/TH800_008.jpg)
英語で発表というのはやや敷居が高くなりますが、
![blockdiagの発表風景 blockdiagの発表風景](/assets/images/news/report/01/europython2011/0004/thumb/TH800_024.jpg)
そして、
![講演の中で使われたseqdiagのダイアグラム 講演の中で使われたseqdiagのダイアグラム](/assets/images/news/report/01/europython2011/0004/thumb/TH800_009.jpg)
その後もblockdiagに数式を記述できるようにしてほしい、
ライトニングトークスという、
開発者から見ると、
ikazuchi
筆者もせっかくの機会なのでikazuchiという翻訳ツールについて発表しました。
7割ぐらいは準備していった通りに進められたのですが、
会場ではスクリーンが発表者の真後ろにありました。ミラーリング機能を無効にしていたため、
慣れない環境や状況で実際にやってみると、
読者の皆さんも臆せず、
PSF membership meeting:PSFメンバーミーティング
本カンファレンスとは直接関係ありませんが、
![PSFミーティングのスライド PSFミーティングのスライド](/assets/images/news/report/01/europython2011/0004/thumb/TH800_010.jpg)
meeting:ミーティング
ミーティングの参加者は25名程度でした。PSFは、
Pythonの実装には、
ミーティングでは、
wikiやメーリングリストでは、
membership election:メンバー投票
PSFメンバーになるには、
今回開かれたPSFメンバーミーティングは、
つい先日、
brochure project:ブローシュアプロジェクト
Pythonの幅広い展開を狙い、
いまは20ページ程度で構成されたパンフレットが用意されています。残念ながら、
Sprint:スプリント
本カンファレンスは月曜日から金曜日までの5日間の開催でしたが、
スプリントは、
今回はCPython,PyPyといった言語処理系から、
小宮さん
![MoinMoinスプリントに参加中の小宮さん MoinMoinスプリントに参加中の小宮さん](/assets/images/news/report/01/europython2011/0004/thumb/TH800_011.jpg)
![PyPyスプリントに参加中の池さん PyPyスプリントに参加中の池さん](/assets/images/news/report/01/europython2011/0004/thumb/TH800_012.jpg)
観光
せっかくの機会なので少し観光もしてきました。筆者は、
季節にもよるのでしょうが、
![19時過ぎのイタリアの明るさ 19時過ぎのイタリアの明るさ](/assets/images/news/report/01/europython2011/0004/thumb/TH800_013.jpg)
Florence:フィレンツェ
フィレンツェは、
![フィレンツェ市街の展望 フィレンツェ市街の展望](/assets/images/news/report/01/europython2011/0004/thumb/TH800_014.jpg)
![夕暮れの教会 夕暮れの教会](/assets/images/news/report/01/europython2011/0004/thumb/TH800_015.jpg)
Roma:ローマ
特に期待して行ったわけではなかったのですが、
![コロッセオ コロッセオ](/assets/images/news/report/01/europython2011/0004/thumb/TH800_016.jpg)
![コロッセオの内部 コロッセオの内部](/assets/images/news/report/01/europython2011/0004/thumb/TH800_017.jpg)
![ヴァチカン市国のサン・ピエトロ大聖堂 ヴァチカン市国のサン・ピエトロ大聖堂](/assets/images/news/report/01/europython2011/0004/thumb/TH800_018.jpg)
![トレヴィの泉でお金を投げ入れる小宮さんと筆者 トレヴィの泉でお金を投げ入れる小宮さんと筆者](/assets/images/news/report/01/europython2011/0004/thumb/TH800_019.jpg)
Dishes:料理
骨付きのお肉は、
![カルボナーラ カルボナーラ](/assets/images/news/report/01/europython2011/0004/thumb/TH800_020.jpg)
![骨付きのお肉(1Kg) 骨付きのお肉(1Kg)](/assets/images/news/report/01/europython2011/0004/thumb/TH800_021.jpg)
![生ハムメロン 生ハムメロン](/assets/images/news/report/01/europython2011/0004/thumb/TH800_022.jpg)
![ピッツァ ピッツァ](/assets/images/news/report/01/europython2011/0004/thumb/TH800_023.jpg)
PyCon JP
PyConというPythonの公式カンファレンスは、
またイベントの雰囲気を掴むには、
あとがき・謝辞
本カンファレンスは、
タイトルの
また、
どんなことでも自身の経験がないことに初めて挑戦するのは不安があります。そんなときに仲間がいて、