12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

一度だけ評価するプロパティ

Last updated at Posted at 2012-08-18

phpでよくあるコードで、こんなものがあります。

<?php
class Foo {
	private $_bar = null;
	public function getBar() {
		if ($this->_bar === null) {
			$this->_bar = Bar::getFromFooId($this->getId());
		}
		return $this->_bar;
	}
}

$foo = new Foo();
$foo->getBar();
$foo->getBar(); // キャッシュが利用される.

特に Twig などのテンプレートエンジンではテンプレート内で {{ foo.bar }} と書いたら $foo->getBar(); が実行されるので、キャッシュをしておかないとなんども同じクエリをDBに発行する可能性があります。

Python で同じことをプロパティを利用して実現するとしたら、次のようになります。

class Foo(object):
	_bar = None
	@property
	def bar(self):
		if self._bar is None:
			self._bar = Bar.from_foo_id(self.id)
		return self._bar

foo = Foo()
foo.bar
foo.bar # キャッシュが利用される

これをもっと簡潔にするのが、 werkzeug というライブラリにある werkzeug.utils.cached_decorator というデコレータです。 (実際には、 Bar.from_foo_id()None を返した時も正しくキャッシュできるので、より優れています)

from werkzeug.utils import cached_property

class Foo(object):
	@cached_property
	def bar(self):
		return Bar.from_foo_id(self.id)

php で7行のコードが、 Python では 3行になりました。キャッシュを実現するための退屈なコード (boilerplate code) がなくなって、本質的なコードだけを書くことができるので、読みやすく、バグを埋め込みにくく見つけやすい、メンテナンス性が高いコードになっています。

この cached_property はデコレータとディスクリプタという機能を使って実装されているのですが、 Python 組み込みの property, staticmethod, classmethod も同じ機能を使って実装されています。

プロパティを持っている言語は幾つかありますし、 php も将来実装するかもしれませんが、 Python は一段階メタな言語機能を実装して、プロパティのような機能は単にその言語機能を利用する組み込みオブジェクトとして実装しているので、構文はシンプルなのに、より柔軟で、現実世界のゴチャゴチャしたアプリケーションをよりすっきり書くことを可能にする能力を持っています。


この記事は主に php や Java のようにオブジェクトシステムが静的な言語のユーザーに Python に興味を持ってもらうことを目的として書いています。 (php は動的型付けだがそれ以外の部分はむしろJavaに近い静的言語)

JavaScript や Ruby のような動的言語なら同じようなことができると思うので、ぜひその方法を紹介してください。できるだけ「こんな書き方もできるぜ(でも実際には使わないけどな)」じゃなくて、現実世界の日々のプログラムを楽にしてくれるような polished な方法をお願いします。

12
13
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?