<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>taichino.com &#187; python</title>
	<atom:link href="http://taichino.com/tag/python/feed" rel="self" type="application/rss+xml" />
	<link>http://taichino.com</link>
	<description>永遠のネバーランド</description>
	<lastBuildDate>Sat, 04 Feb 2012 13:33:04 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>DjangoでJinja2を使いたいという話</title>
		<link>http://taichino.com/programming/2255</link>
		<comments>http://taichino.com/programming/2255#comments</comments>
		<pubDate>Wed, 12 Oct 2011 16:31:48 +0000</pubDate>
		<dc:creator>taichino</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[jinja2]]></category>

		<guid isPermaLink="false">http://taichino.com/?p=2255</guid>
		<description><![CDATA[先ほどの記事にも書いたようにAppStatsは、Kay frameworkで途中まで書いたコードをDjangoに移植したんですが、その際にテンプレートエンジンの差異に少し戸惑いました。 Kayで採用されているjinja2はDjangoの標準テンプレートに良く似せて作られていて、Djangoを触った事があれば違和感無く使い始められます。ところがDjangoでイマイチな部分が解消されていて、一度jinja2を使ってしまうとDjangoに戻ってきた時にイライラしてしまうという問題が生じます。jinja2の何が良いかというと、例えばdjangoのドット記法はヤダとか、テンプレート中で関数呼び出しを見慣れている形で記述できるとか、デフォで{% macro %}が使える等などです。 正直macroなんかは一回使ったらもう同等機能がないテンプレートシステムなんて使えないです。という訳でDjangoでもjinja2を使いたいということで、調べた方法を記録しておきます。 ありがたい事にDjangoにはテンプレートのローダーをプラガブルに設定する仕組みが備わっています。なので下記のようなシンプルな手順でjinja2を使えるようになりました。 jinja2用のテンプレートローダを記述 &#8211; jinja2にKayのurl_forにあたるURL逆引き関数を設定 &#8211; jinja2にi18nの設定を行う settings.pyに1のローダを指定 1. jinja2用のローダを記述 ローダはgistに張られていたコチラのコードをほぼ丸パクリさせてもらいました。修正したポイントは上記の2点です。まず今回Kayからの移植という事もあり、URLの逆引き関数が必要だったので、django.core.urlresolvers.reverseをテンプレート中で使えるようにしています。関数名はKayに合わせてurl_forました。もう一点はi18nの設定です。jinja2には国際化を行う為のクラスを指定する仕組みが備わっているので、そこにDjangoの翻訳モジュールを指定します。こうするとDjangoで作成できる.poファイルをjinja2からそのまま利用できます。 あと補足ですが、このローダは拡張子が.htmlのものをロードしません。なのでDjango標準のテンプレートとjinja2のテンプレートを共存させられます。 from django.core.urlresolvers import get_callable from django.template import TemplateDoesNotExist from django.template.loader import BaseLoader from django.template.context import BaseContext from django.conf import settings from django.utils import translation from django.core import urlresolvers &#160; import jinja2 &#160; def monkey_patch_django&#40;&#41;: &#34;&#34;&#34; Patching some django [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://taichino.com/programming/2231">先ほどの記事</a>にも書いたように<a href="http://ios.app-stats.info/ja/pc">AppStats</a>は、<a href="http://code.google.com/p/kay-framework/">Kay framework</a>で途中まで書いたコードをDjangoに移植したんですが、その際にテンプレートエンジンの差異に少し戸惑いました。</p>
<p>Kayで採用されている<a href="http://jinja.pocoo.org/docs/">jinja2</a>はDjangoの標準テンプレートに良く似せて作られていて、Djangoを触った事があれば違和感無く使い始められます。ところがDjangoでイマイチな部分が解消されていて、一度jinja2を使ってしまうとDjangoに戻ってきた時にイライラしてしまうという問題が生じます。jinja2の何が良いかというと、例えばdjangoのドット記法はヤダとか、テンプレート中で関数呼び出しを見慣れている形で記述できるとか、デフォで{% macro %}が使える等などです。</p>
<p>正直macroなんかは一回使ったらもう同等機能がないテンプレートシステムなんて使えないです。という訳でDjangoでもjinja2を使いたいということで、調べた方法を記録しておきます。</p>
<p><span id="more-2255"></span></p>
<p>ありがたい事にDjangoにはテンプレートのローダーをプラガブルに設定する仕組みが備わっています。なので下記のようなシンプルな手順でjinja2を使えるようになりました。</p>
<ol>
<li> jinja2用のテンプレートローダを記述<br />
   &#8211; jinja2にKayのurl_forにあたるURL逆引き関数を設定<br />
   &#8211; jinja2にi18nの設定を行う
</li>
<li>settings.pyに1のローダを指定</li>
</ol>
<p><strong>1. jinja2用のローダを記述</strong><br />
ローダはgistに張られていた<a href="http://djangosnippets.org/snippets/363/">コチラのコード</a>をほぼ丸パクリさせてもらいました。修正したポイントは上記の2点です。まず今回Kayからの移植という事もあり、URLの逆引き関数が必要だったので、django.core.urlresolvers.reverseをテンプレート中で使えるようにしています。関数名はKayに合わせてurl_forました。もう一点はi18nの設定です。jinja2には国際化を行う為のクラスを指定する仕組みが備わっているので、そこにDjangoの翻訳モジュールを指定します。こうするとDjangoで作成できる.poファイルをjinja2からそのまま利用できます。</p>
<p>あと補足ですが、このローダは拡張子が.htmlのものをロードしません。なのでDjango標準のテンプレートとjinja2のテンプレートを共存させられます。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span>.<span style="color: black;">urlresolvers</span> <span style="color: #ff7700;font-weight:bold;">import</span> get_callable
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span> <span style="color: #ff7700;font-weight:bold;">import</span> TemplateDoesNotExist
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span>.<span style="color: black;">loader</span> <span style="color: #ff7700;font-weight:bold;">import</span> BaseLoader
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span>.<span style="color: black;">context</span> <span style="color: #ff7700;font-weight:bold;">import</span> BaseContext
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span> <span style="color: #ff7700;font-weight:bold;">import</span> settings
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span> <span style="color: #ff7700;font-weight:bold;">import</span> translation
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> urlresolvers
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> jinja2
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> monkey_patch_django<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    Patching some django objects to make them &quot;safe&quot; for jinja's escape() function.
    Good for us it uses __html__() method.
    &quot;&quot;&quot;</span>
    <span style="color: #808080; font-style: italic;"># Django's SafeString and SafeUnicode should not be escaped:</span>
    <span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">safestring</span> <span style="color: #ff7700;font-weight:bold;">import</span> SafeData
    SafeData.__html__ = <span style="color: #ff7700;font-weight:bold;">lambda</span> <span style="color: #008000;">self</span>: <span style="color: #008000;">self</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">from</span> jinja2 <span style="color: #ff7700;font-weight:bold;">import</span> escape
    <span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">forms</span> <span style="color: #ff7700;font-weight:bold;">import</span> BaseForm, Media
    <span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">forms</span>.<span style="color: black;">forms</span> <span style="color: #ff7700;font-weight:bold;">import</span> BoundField
    <span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">forms</span>.<span style="color: black;">formsets</span> <span style="color: #ff7700;font-weight:bold;">import</span> BaseFormSet
    <span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">forms</span>.<span style="color: black;">util</span> <span style="color: #ff7700;font-weight:bold;">import</span> ErrorDict, ErrorList
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> cls <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#40;</span>BaseForm, Media, BoundField, BaseFormSet, ErrorDict, ErrorList<span style="color: black;">&#41;</span>:
        cls.__html__ = <span style="color: #ff7700;font-weight:bold;">lambda</span> <span style="color: #008000;">self</span>: escape<span style="color: black;">&#40;</span><span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Template<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    A container for jinja2 Template class
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, template, origin=<span style="color: #008000;">None</span>, name=<span style="color: #483d8b;">'&lt;unknown Template&gt;'</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">template</span> = template
        <span style="color: #008000;">self</span>.<span style="color: black;">origin</span> = origin
        <span style="color: #008000;">self</span>.<span style="color: black;">name</span> = name
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> render<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, context<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>context, BaseContext<span style="color: black;">&#41;</span>:
            d = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
            <span style="color: #ff7700;font-weight:bold;">for</span> u <span style="color: #ff7700;font-weight:bold;">in</span> context.<span style="color: black;">dicts</span>:
                d.<span style="color: black;">update</span><span style="color: black;">&#40;</span>u<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            d = context
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">template</span>.<span style="color: black;">render</span><span style="color: black;">&#40;</span>d<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Loader<span style="color: black;">&#40;</span>BaseLoader<span style="color: black;">&#41;</span>:
    is_usable = <span style="color: #008000;">True</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;
        Creating jinja2 environment
        &quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span>settings, <span style="color: #483d8b;">'TEMPLATE_DIRS'</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'Jinja2 template loader needs TEMPLATE_DIRS setting'</span>
        monkey_patch_django<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        extras = <span style="color: #008000;">self</span>._get_env_extras<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        options = <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>settings, <span style="color: #483d8b;">'JINJA2_ENVIRONMENT_OPTIONS'</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
        options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'extensions'</span><span style="color: black;">&#93;</span> = extras<span style="color: black;">&#91;</span><span style="color: #483d8b;">'extensions'</span><span style="color: black;">&#93;</span>
        options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'loader'</span><span style="color: black;">&#93;</span> = jinja2.<span style="color: black;">FileSystemLoader</span><span style="color: black;">&#40;</span>settings.<span style="color: black;">TEMPLATE_DIRS</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">### Some special tuning of jinja2 environment goes here</span>
        <span style="color: #808080; font-style: italic;"># Number of compiled jinja2 templates in process memory</span>
        options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'cache_size'</span><span style="color: black;">&#93;</span> = -<span style="color: #ff4500;">1</span>
        <span style="color: #808080; font-style: italic;"># Check whether template file is changed only in development</span>
        options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'auto_reload'</span><span style="color: black;">&#93;</span> = settings.<span style="color: black;">DEBUG</span>
        <span style="color: #808080; font-style: italic;"># Use jinja's bytecode cache</span>
        options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'bytecode_cache'</span><span style="color: black;">&#93;</span> = jinja2.<span style="color: black;">FileSystemBytecodeCache</span><span style="color: black;">&#40;</span>settings.<span style="color: black;">BASE_DIR</span> + <span style="color: #483d8b;">'/tmp/jinja_cache'</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">env</span> = jinja2.<span style="color: black;">Environment</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">**</span>options<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: black;">filters</span>.<span style="color: black;">update</span><span style="color: black;">&#40;</span>extras<span style="color: black;">&#91;</span><span style="color: #483d8b;">'filters'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: #008000;">globals</span>.<span style="color: black;">update</span><span style="color: black;">&#40;</span>extras<span style="color: black;">&#91;</span><span style="color: #483d8b;">'globals'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: black;">tests</span>.<span style="color: black;">update</span><span style="color: black;">&#40;</span>extras<span style="color: black;">&#91;</span><span style="color: #483d8b;">'tests'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># 1. urlresolvers.reverseをurl_forとして登録</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: #008000;">globals</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'url_for'</span><span style="color: black;">&#93;</span> = urlresolvers.<span style="color: black;">reverse</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># 2. djangoの翻訳モジュールをjinjaに登録</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">'jinja2.ext.i18n'</span> <span style="color: #ff7700;font-weight:bold;">in</span> options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'extensions'</span><span style="color: black;">&#93;</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: black;">install_gettext_translations</span><span style="color: black;">&#40;</span>translation<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _get_env_extras<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;
        Creates a dict of extensions, filters, globals and tests from settings
        &quot;&quot;&quot;</span>
        extensions, filters, objects, tests = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># add the globally defined extension list</span>
        extensions.<span style="color: black;">extend</span><span style="color: black;">&#40;</span><span style="color: #008000;">list</span><span style="color: black;">&#40;</span><span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>settings, <span style="color: #483d8b;">'JINJA2_EXTENSIONS'</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># parse filters, globals and tests settings</span>
        <span style="color: #ff7700;font-weight:bold;">def</span> from_setting<span style="color: black;">&#40;</span>setting<span style="color: black;">&#41;</span>:
            retval = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
            setting = <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>settings, setting, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>setting, <span style="color: #008000;">dict</span><span style="color: black;">&#41;</span>:
                <span style="color: #ff7700;font-weight:bold;">for</span> key, value <span style="color: #ff7700;font-weight:bold;">in</span> setting.<span style="color: black;">iteritems</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
                    retval<span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span> = <span style="color: #008000;">callable</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> value <span style="color: #ff7700;font-weight:bold;">or</span> get_callable<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">for</span> value <span style="color: #ff7700;font-weight:bold;">in</span> setting:
                    value = <span style="color: #008000;">callable</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> value <span style="color: #ff7700;font-weight:bold;">or</span> get_callable<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>
                    retval<span style="color: black;">&#91;</span>value.__name__<span style="color: black;">&#93;</span> = value
            <span style="color: #ff7700;font-weight:bold;">return</span> retval
&nbsp;
        filters.<span style="color: black;">update</span><span style="color: black;">&#40;</span>from_setting<span style="color: black;">&#40;</span><span style="color: #483d8b;">'JINJA2_FILTERS'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        objects.<span style="color: black;">update</span><span style="color: black;">&#40;</span>from_setting<span style="color: black;">&#40;</span><span style="color: #483d8b;">'JINJA2_GLOBALS'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        tests.<span style="color: black;">update</span><span style="color: black;">&#40;</span>from_setting<span style="color: black;">&#40;</span><span style="color: #483d8b;">'JINJA2_TESTS'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>
            extensions=extensions,
            filters=filters,
            <span style="color: #008000;">globals</span>=objects,
            tests=tests,
        <span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> load_template<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, template_name, template_dirs=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># Leave .html extension for django template (admin, contrib, etc)</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> template_name.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.html'</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateDoesNotExist<span style="color: black;">&#40;</span>template_name<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            template = <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: black;">get_template</span><span style="color: black;">&#40;</span>template_name<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> Template<span style="color: black;">&#40;</span>template, <span style="color: #008000;">None</span>, template_name<span style="color: black;">&#41;</span>, <span style="color: #008000;">None</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> jinja2.<span style="color: black;">TemplateNotFound</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateDoesNotExist<span style="color: black;">&#40;</span>template_name<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> load_template_source<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, template_name, template_dirs=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># Leave .html extension for django template (admin, contrib, etc)</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> template_name.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.html'</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateDoesNotExist<span style="color: black;">&#40;</span>template_name<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            source, filename, uptodate = <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: black;">loader</span>.<span style="color: black;">get_source</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">env</span>, template_name<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> source, filename
        <span style="color: #ff7700;font-weight:bold;">except</span> jinja2.<span style="color: black;">TemplateNotFound</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateDoesNotExist<span style="color: black;">&#40;</span>template_name<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>/unknown<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p><strong>2. settings.pyに1のローダを指定</strong><br />
次に1で作ったローダをsettings.pyに記述しましょう。同時にJINJA2_EXTENSIONSも記述します。<br />
また自分のフィルタを追加する場合はJINJA2_FILTERSに追記すればOKです。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">TEMPLATE_LOADERS = <span style="color: black;">&#40;</span>
  <span style="color: #483d8b;">'jinjalink_loader.Loader'</span>,
  <span style="color: #483d8b;">'django.template.loaders.filesystem.Loader'</span>,
  <span style="color: #483d8b;">'django.template.loaders.app_directories.Loader'</span>,
<span style="color: black;">&#41;</span>
&nbsp;
JINJA2_EXTENSIONS = <span style="color: black;">&#40;</span>
  <span style="color: #483d8b;">'jinja2.ext.with_'</span>,
  <span style="color: #483d8b;">'jinja2.ext.i18n'</span>,
<span style="color: black;">&#41;</span>
JINJA2_FILTERS = <span style="color: black;">&#123;</span>
  ...
<span style="color: black;">&#125;</span>
JINJA2_ENVIRONMENT_OPTIONS = <span style="color: black;">&#123;</span>
  ...
<span style="color: black;">&#125;</span></pre></div></div>

<p>以上でjinja2をDjangoから使えるようになりました。jinja2は本当に便利で、Django使うのがさらに楽しくなるのでオススメです。あとどうでも良いんですが、jinja2のテンプレートの拡張子って皆さん何使ってるんでしょうか。僕はもっぱら.j2なんですけど。</p>
]]></content:encoded>
			<wfw:commentRss>http://taichino.com/programming/2255/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hello Tcl/Tk World</title>
		<link>http://taichino.com/programming/2054</link>
		<comments>http://taichino.com/programming/2054#comments</comments>
		<pubDate>Sun, 19 Dec 2010 23:44:21 +0000</pubDate>
		<dc:creator>taichino</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tcl/tk]]></category>

		<guid isPermaLink="false">http://taichino.com/?p=2054</guid>
		<description><![CDATA[GUIっぽい実験するのにTcl/Tkが良いんじゃないかっていう事で、ちょっとかじってみる事にしました。とりあえずtclでfizzbuzzやってみたのが以下になります。インタプリタのコマンドはtclshです。情報源としては公式ドキュメントのチュートリアルを最速文法マスター見ながらなめれば何となくならコード書けるかなぁと思います。 #!/usr/bin/tclsh &#160; for &#123;set i 1&#125; &#123;$i &#60; 100&#125; &#123;incr i&#125; &#123; if &#123;&#91;expr $i % 15&#93; == 0&#125; &#123; puts &#34;$i: FizzBuzz&#34; &#125; elseif &#123;&#91;expr $i % 3&#93; == 0&#125; &#123; puts &#34;$i: Fizz&#34; &#125; elseif &#123;&#91;expr $i % 5&#93; == 0&#125; &#123; puts &#34;$i: Buzz&#34; &#125; &#125; ついでにnabeatzzもやってみました。練習材料としてはfizzbuzzより遥かに優れているので、これから新しい言語触る時はとりあえずやっとけば良いんじゃないかと思います。 #!/usr/bin/tclsh &#160; set numdic [...]]]></description>
			<content:encoded><![CDATA[<p>GUIっぽい実験するのにTcl/Tkが良いんじゃないかっていう事で、ちょっとかじってみる事にしました。とりあえずtclでfizzbuzzやってみたのが以下になります。インタプリタのコマンドはtclshです。情報源としては<a href="http://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html">公式ドキュメントのチュートリアル</a>を<a href="http://pyomeha.blog42.fc2.com/blog-entry-6.html">最速文法マスター</a>見ながらなめれば何となくならコード書けるかなぁと思います。</p>
<p><span id="more-2054"></span></p>

<div class="wp_syntax"><div class="code"><pre class="tcl" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/tclsh</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#123;</span><span style="color: #ff7700;font-weight:bold;">set</span> i <span style="color: #ff4500;">1</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span><span style="color: #ff3333;">$i</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">100</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span><span style="color: #008000;">incr</span> i<span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#123;</span><span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$i</span> <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">15</span><span style="color: black;">&#93;</span> == <span style="color: #ff4500;">0</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
	<span style="color: #008000;">puts</span> <span style="color: #483d8b;">&quot;$i: FizzBuzz&quot;</span>
    <span style="color: black;">&#125;</span> <span style="color: #ff7700;font-weight:bold;">elseif</span> <span style="color: black;">&#123;</span><span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$i</span> <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span> == <span style="color: #ff4500;">0</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
	<span style="color: #008000;">puts</span> <span style="color: #483d8b;">&quot;$i: Fizz&quot;</span>
    <span style="color: black;">&#125;</span> <span style="color: #ff7700;font-weight:bold;">elseif</span> <span style="color: black;">&#123;</span><span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$i</span> <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">5</span><span style="color: black;">&#93;</span> == <span style="color: #ff4500;">0</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
	<span style="color: #008000;">puts</span> <span style="color: #483d8b;">&quot;$i: Buzz&quot;</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span></pre></div></div>

<p>ついでに<a href="http://mattn.kaoriya.net/software/vim/20080306202201.htm">nabeatzz</a>もやってみました。練習材料としてはfizzbuzzより遥かに優れているので、これから新しい言語触る時はとりあえずやっとけば良いんじゃないかと思います。
</pre>

<div class="wp_syntax"><div class="code"><pre class="tcl" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/tclsh</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">set</span> numdic <span style="color: black;">&#91;</span>dict create<span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> numdic <span style="color: #ff4500;">0</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;ぜろ&quot;</span> <span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> numdic <span style="color: #ff4500;">1</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;いち&quot;</span> <span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> numdic <span style="color: #ff4500;">2</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;に&quot;</span>   <span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> numdic <span style="color: #ff4500;">3</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;さん&quot;</span> <span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> numdic <span style="color: #ff4500;">4</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;よん&quot;</span> <span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> numdic <span style="color: #ff4500;">5</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;ご&quot;</span>   <span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> numdic <span style="color: #ff4500;">6</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;ろく&quot;</span> <span style="color: #ff4500;">3</span> <span style="color: #483d8b;">&quot;ろっ&quot;</span><span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> numdic <span style="color: #ff4500;">7</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;なな&quot;</span> <span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> numdic <span style="color: #ff4500;">8</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;はち&quot;</span> <span style="color: #ff4500;">3</span> <span style="color: #483d8b;">&quot;はっ&quot;</span> <span style="color: #ff4500;">4</span> <span style="color: #483d8b;">&quot;はっ&quot;</span> <span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> numdic <span style="color: #ff4500;">9</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;きゅう&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">set</span> digdic <span style="color: black;">&#91;</span>dict create<span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> digdic <span style="color: #ff4500;">1</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;&quot;</span> <span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> digdic <span style="color: #ff4500;">2</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;じゅう&quot;</span> <span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> digdic <span style="color: #ff4500;">3</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;ひゃく&quot;</span> <span style="color: #ff4500;">3</span> <span style="color: #483d8b;">&quot;びゃく&quot;</span> <span style="color: #ff4500;">6</span> <span style="color: #483d8b;">&quot;ぴゃく&quot;</span> <span style="color: #ff4500;">8</span> <span style="color: #483d8b;">&quot;ぴゃく&quot;</span><span style="color: black;">&#93;</span>
dict <span style="color: #ff7700;font-weight:bold;">set</span> digdic <span style="color: #ff4500;">4</span> <span style="color: black;">&#91;</span>dict create <span style="color: #ff4500;">0</span> <span style="color: #483d8b;">&quot;せん&quot;</span> <span style="color: #ff4500;">3</span> <span style="color: #483d8b;">&quot;ぜん&quot;</span> <span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">proc</span> num2ja <span style="color: black;">&#123;</span> num <span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
    <span style="color: #ff7700;font-weight:bold;">global</span> numdic
    <span style="color: #ff7700;font-weight:bold;">global</span> digdic
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#123;</span> <span style="color: #ff3333;">$num</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">0</span> || <span style="color: #ff3333;">$num</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">9999</span> <span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
	<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;$num: あほなのでわかりませーん&quot;</span>
    <span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">set</span> len <span style="color: black;">&#91;</span><span style="color: #008000;">string</span> length <span style="color: #ff3333;">$num</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">set</span> n <span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">set</span> ret <span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: black;">&#123;</span><span style="color: #ff3333;">$n</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff3333;">$len</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
	<span style="color: #ff7700;font-weight:bold;">set</span> place <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$len</span> - <span style="color: #ff3333;">$n</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">set</span> base <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span> <span style="color: #66cc66;">**</span> <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$place</span> - <span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">set</span> number <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$num</span> / <span style="color: #ff3333;">$base</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">set</span> numIndex <span style="color: #ff4500;">0</span>
	<span style="color: #ff7700;font-weight:bold;">set</span> digIndex <span style="color: #ff4500;">0</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#123;</span> <span style="color: black;">&#91;</span>dict exists <span style="color: black;">&#91;</span>dict get <span style="color: #ff3333;">$digdic</span> <span style="color: #ff3333;">$place</span><span style="color: black;">&#93;</span> <span style="color: #ff3333;">$number</span><span style="color: black;">&#93;</span> <span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
	    <span style="color: #ff7700;font-weight:bold;">set</span> digIndex <span style="color: #ff3333;">$number</span>
	<span style="color: black;">&#125;</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#123;</span> <span style="color: black;">&#91;</span>dict exists <span style="color: black;">&#91;</span>dict get <span style="color: #ff3333;">$numdic</span> <span style="color: #ff3333;">$number</span><span style="color: black;">&#93;</span> <span style="color: #ff3333;">$place</span><span style="color: black;">&#93;</span> <span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
	    <span style="color: #ff7700;font-weight:bold;">set</span> numIndex <span style="color: #ff3333;">$place</span>
	<span style="color: black;">&#125;</span>
	<span style="color: #ff7700;font-weight:bold;">set</span> strDigit  <span style="color: black;">&#91;</span>dict get <span style="color: black;">&#91;</span>dict get <span style="color: #ff3333;">$digdic</span> <span style="color: #ff3333;">$place</span><span style="color: black;">&#93;</span>  <span style="color: #ff3333;">$digIndex</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">set</span> strNumber <span style="color: black;">&#91;</span>dict get <span style="color: black;">&#91;</span>dict get <span style="color: #ff3333;">$numdic</span> <span style="color: #ff3333;">$number</span><span style="color: black;">&#93;</span> <span style="color: #ff3333;">$numIndex</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#123;</span> <span style="color: #66cc66;">!</span><span style="color: black;">&#40;</span><span style="color: #ff3333;">$number</span> == <span style="color: #ff4500;">0</span> || <span style="color: black;">&#40;</span><span style="color: #ff3333;">$number</span> == <span style="color: #ff4500;">1</span> <span style="color: #66cc66;">&amp;&amp;</span> <span style="color: #ff3333;">$place</span> <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
	    <span style="color: #008000;">append</span> ret <span style="color: #ff3333;">$strNumber</span>
	<span style="color: black;">&#125;</span>
	<span style="color: #008000;">append</span> ret <span style="color: #ff3333;">$strDigit</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">set</span> num <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$num</span> - <span style="color: black;">&#40;</span><span style="color: #ff3333;">$base</span> <span style="color: #66cc66;">*</span> <span style="color: #ff3333;">$number</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">set</span> n <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$n</span> + <span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
    <span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff3333;">$ret</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">set</span> cnt <span style="color: #ff4500;">40</span>
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#123;</span><span style="color: #008000;"><span style="color: #ff3333;">$argc</span></span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span> <span style="color: #ff7700;font-weight:bold;">set</span> cnt <span style="color: #008000;"><span style="color: #ff3333;">$argv</span></span> <span style="color: black;">&#125;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#123;</span><span style="color: #ff7700;font-weight:bold;">set</span> i <span style="color: #ff4500;">1</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span><span style="color: #ff3333;">$i</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff3333;">$cnt</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span><span style="color: #008000;">incr</span> i<span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#123;</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$i</span> <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span> == <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> || <span style="color: black;">&#91;</span><span style="color: #008000;">string</span> match <span style="color: #66cc66;">*</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">*</span> <span style="color: #ff3333;">$i</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
	<span style="color: #008000;">puts</span> <span style="color: #483d8b;">&quot;$i [num2ja $i]&quot;</span>
    <span style="color: black;">&#125;</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: black;">&#123;</span>
	<span style="color: #008000;">puts</span> <span style="color: #483d8b;">&quot;$i&quot;</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span></pre></div></div>

<p>知ってる他の言語と、そこまで違いは無いんですが、変数の参照時のみ$が必要というのが面倒なのと、辞書にシンタックスシュガーがあったらなぁという印象です。あと[ ]で囲った部分が先に評価されて結果で置換されるのも特徴的で、関数呼び出し周辺はObjetive-Cみたいな見た目になります。</p>
<p>さてヨチヨチ歩きでtclが書けるようになったところでtkを試してみます。tkもtclと同様<a href="http://www.tkdocs.com/tutorial/">公式ドキュメントのチュートリアル</a>がやけに気合いが入っていて、例題ごとにtcl, perl, ruby, pythonの各言語用のバインディングにあわせて解説がされています。pythonのバインディングのサンプルが手元で動かなかったのが残念ですが。。。</p>
<p>何はともあれ円が壁に当たったら跳ね返るサンプルが以下になります。あまり理解していませんがGUIなtclコード書く時はtclshではなくてwishを使うのが通例のようです。
</pre>

<div class="wp_syntax"><div class="code"><pre class="tcl" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/wish</span>
&nbsp;
<span style="color: #008000;">package</span> require Tk
&nbsp;
<span style="color: #ff7700;font-weight:bold;">proc</span> random <span style="color: black;">&#123;</span><span style="color: black;">&#123;</span>range <span style="color: #ff4500;">100</span><span style="color: black;">&#125;</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: black;">&#123;</span>int<span style="color: black;">&#40;</span>rand<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #ff3333;">$range</span><span style="color: black;">&#41;</span><span style="color: black;">&#125;</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#125;</span>
&nbsp;
wm geometry . 300x200
&nbsp;
grid <span style="color: black;">&#91;</span>tk::<span style="color: black;">canvas</span> .canvas<span style="color: black;">&#93;</span>
grid configure <span style="color: #483d8b;">&quot;.canvas&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">set</span> radius <span style="color: black;">&#91;</span>random <span style="color: #ff4500;">30</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">set</span> x <span style="color: #ff4500;">20</span>
<span style="color: #ff7700;font-weight:bold;">set</span> y <span style="color: #ff4500;">10</span>
<span style="color: #ff7700;font-weight:bold;">set</span> circle <span style="color: black;">&#91;</span>.canvas create oval <span style="color: #ff3333;">$x</span> <span style="color: #ff3333;">$y</span> <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$x</span> + <span style="color: #ff3333;">$radius</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$y</span> + <span style="color: #ff3333;">$radius</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">set</span> v_x <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: black;">&#91;</span>random <span style="color: #ff4500;">10</span><span style="color: black;">&#93;</span> + <span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">set</span> v_y <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: black;">&#91;</span>random <span style="color: #ff4500;">10</span><span style="color: black;">&#93;</span> + <span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">proc</span> update <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
    <span style="color: #ff7700;font-weight:bold;">global</span> circle v_x v_y
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">set</span> coords <span style="color: black;">&#91;</span>.canvas coords <span style="color: #ff3333;">$circle</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">set</span> x1 <span style="color: black;">&#91;</span><span style="color: #008000;">lindex</span> <span style="color: #ff3333;">$coords</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">set</span> y1 <span style="color: black;">&#91;</span><span style="color: #008000;">lindex</span> <span style="color: #ff3333;">$coords</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">set</span> x2 <span style="color: black;">&#91;</span><span style="color: #008000;">lindex</span> <span style="color: #ff3333;">$coords</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">set</span> y2 <span style="color: black;">&#91;</span><span style="color: #008000;">lindex</span> <span style="color: #ff3333;">$coords</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">set</span> x1 <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$x1</span> + <span style="color: #ff3333;">$v_x</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">set</span> y1 <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$y1</span> + <span style="color: #ff3333;">$v_y</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">set</span> x2 <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$x2</span> + <span style="color: #ff3333;">$v_x</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">set</span> y2 <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$y2</span> + <span style="color: #ff3333;">$v_y</span><span style="color: black;">&#93;</span>    
&nbsp;
    .canvas coords <span style="color: #ff3333;">$circle</span> <span style="color: #ff3333;">$x1</span> <span style="color: #ff3333;">$y1</span> <span style="color: #ff3333;">$x2</span> <span style="color: #ff3333;">$y2</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#123;</span> <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$x1</span> + <span style="color: #ff3333;">$v_x</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">0</span> || <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$x2</span> + <span style="color: #ff3333;">$v_x</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">300</span> <span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
    	<span style="color: #ff7700;font-weight:bold;">set</span> v_x -<span style="color: #ff3333;">$v_x</span>
    <span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#123;</span> <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$y1</span> + <span style="color: #ff3333;">$v_y</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">0</span> || <span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">expr</span> <span style="color: #ff3333;">$y2</span> + <span style="color: #ff3333;">$v_y</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">200</span> <span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span>
    	<span style="color: #ff7700;font-weight:bold;">set</span> v_y -<span style="color: #ff3333;">$v_y</span>
    <span style="color: black;">&#125;</span>
    after <span style="color: #ff4500;">100</span> update
<span style="color: black;">&#125;</span>
&nbsp;
update</pre></div></div>

<p>とりあえずtcl/tkを触ってみたものの、やっぱりtclよりpythonの方が使いやすいです。せっかくpythonバンディングが準備されているので上記のサンプルを書き換えてみました。タプルのおかげでシンプルに短く記述できますね。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">Tkinter</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">random</span>
&nbsp;
i = <span style="color: #ff4500;">0</span>
root = <span style="color: #dc143c;">Tkinter</span>.<span style="color: black;">Tk</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
root.<span style="color: black;">geometry</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;300x200&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
canvas = <span style="color: #dc143c;">Tkinter</span>.<span style="color: black;">Canvas</span><span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
canvas.<span style="color: black;">pack</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: black;">&#40;</span>x, y, r<span style="color: black;">&#41;</span> = <span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span>, <span style="color: #ff4500;">20</span>, <span style="color: #dc143c;">random</span>.<span style="color: black;">randint</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">30</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#40;</span>v_x, v_y<span style="color: black;">&#41;</span> = <span style="color: black;">&#40;</span><span style="color: #dc143c;">random</span>.<span style="color: black;">randint</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>, <span style="color: #dc143c;">random</span>.<span style="color: black;">randint</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
circle = canvas.<span style="color: black;">create_oval</span><span style="color: black;">&#40;</span>x, y, x+r, y+r<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> loop<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">global</span> circle, v_x, v_y
  <span style="color: black;">&#40;</span>x1, y1, x2, y2<span style="color: black;">&#41;</span> = canvas.<span style="color: black;">coords</span><span style="color: black;">&#40;</span>circle<span style="color: black;">&#41;</span>
  <span style="color: black;">&#40;</span>x1, y1, x2, y2<span style="color: black;">&#41;</span> = <span style="color: black;">&#40;</span>x1 + v_x, y1 + v_y, x2 + v_x, y2 + v_y<span style="color: black;">&#41;</span>
  canvas.<span style="color: black;">coords</span><span style="color: black;">&#40;</span>circle, x1, y1, x2, y2<span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">if</span> x1 + v_x <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">or</span> x2 + v_x <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">300</span>:
    v_x = -v_x
  <span style="color: #ff7700;font-weight:bold;">if</span> y1 + v_y <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">or</span> y2 + v_y <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">200</span>:
    v_y = -v_y
  root.<span style="color: black;">after</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100</span>, loop<span style="color: black;">&#41;</span>
loop<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
root.<span style="color: black;">mainloop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>結局tclじゃなくてpythonからtkを叩くことになりそうですが、tkはちょっとしたGUIアプリとか描画の実験なんかには重宝しそうです。もうちょっと色々と触ってみようと思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://taichino.com/programming/2054/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PythonでMovableTypeのXML-RPCインターフェースを叩く</title>
		<link>http://taichino.com/memo/2045</link>
		<comments>http://taichino.com/memo/2045#comments</comments>
		<pubDate>Thu, 25 Nov 2010 16:53:31 +0000</pubDate>
		<dc:creator>taichino</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[メモ]]></category>
		<category><![CDATA[movable type]]></category>
		<category><![CDATA[xmlrpclib]]></category>

		<guid isPermaLink="false">http://taichino.com/?p=2045</guid>
		<description><![CDATA[MovableTypeにはXML-RPCインターフェースが準備されているので、外部から新しい記事を投稿したり過去の記事を取得したりできます。MT自体のリファレンスを探せなかったので、コチラのページを参考にさせて頂きました。 さてPythonでXML-RPCインターフェースを叩くのにはxmlrpclibを使います。まず以下でサポートしているAPIの一覧を取得してみましょう。これでXML-RPCのURLを確認できます。 import xmlrpclib &#160; rpc_url = 'http://url/to/mt-xmlrpc.cgi' api = xmlrpclib.ServerProxy&#40;rpc_url&#41; print api.mt.supportedMethods&#40;&#41; 次に記事の投稿をしたいのですが、その為にはユーザ名とウェブサービスパスワードが必要です。ログインパスワードでは無いので注意してください。僕はかなりハマりました。ウェブサービスパスワードはログイン後の画面の右上にある「こんにちは○○さん」をクリックすると遷移できる「ユーザ情報の編集」画面で確認できます。 ウェブサービスパスワードを確認したら記事を投稿してみます。ここで注意するべきなのはblog_idが文字列である事と、mt_text_moreで「キー名=値」とするとカスタムフィールドデータを渡せる事です。 import xmlrpclib from pit import Pit &#160; api_url = 'http://url/to/mt-xmlrpc.cgi' &#160; blog_id = '1' config = Pit.get&#40;'taichino@mt'&#41; user = configu&#91;'user'&#93; passwd = config&#91;'pass'&#93; post = &#123;'title' : 'title from xmlrpc', 'description' : 'this is a body and custom', 'dateCreated' : [...]]]></description>
			<content:encoded><![CDATA[<p>MovableTypeにはXML-RPCインターフェースが準備されているので、外部から新しい記事を投稿したり過去の記事を取得したりできます。MT自体のリファレンスを探せなかったので、<a href="http://www.na.rim.or.jp/~tsupo/program/blogTool/mt_xmlRpc.html">コチラ</a>のページを参考にさせて頂きました。</p>
<p><span id="more-2045"></span></p>
<p>さてPythonでXML-RPCインターフェースを叩くのにはxmlrpclibを使います。まず以下でサポートしているAPIの一覧を取得してみましょう。これでXML-RPCのURLを確認できます。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">xmlrpclib</span>
&nbsp;
rpc_url = <span style="color: #483d8b;">'http://url/to/mt-xmlrpc.cgi'</span>
api = <span style="color: #dc143c;">xmlrpclib</span>.<span style="color: black;">ServerProxy</span><span style="color: black;">&#40;</span>rpc_url<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> api.<span style="color: black;">mt</span>.<span style="color: black;">supportedMethods</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>次に記事の投稿をしたいのですが、その為にはユーザ名とウェブサービスパスワードが必要です。ログインパスワードでは無いので注意してください。僕はかなりハマりました。ウェブサービスパスワードはログイン後の画面の右上にある「こんにちは○○さん」をクリックすると遷移できる「ユーザ情報の編集」画面で確認できます。</p>
<p>ウェブサービスパスワードを確認したら記事を投稿してみます。ここで注意するべきなのはblog_idが文字列である事と、mt_text_moreで「キー名=値」とするとカスタムフィールドデータを渡せる事です。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">xmlrpclib</span>
<span style="color: #ff7700;font-weight:bold;">from</span> pit <span style="color: #ff7700;font-weight:bold;">import</span> Pit
&nbsp;
api_url = <span style="color: #483d8b;">'http://url/to/mt-xmlrpc.cgi'</span>
&nbsp;
blog_id = <span style="color: #483d8b;">'1'</span>
config = Pit.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'taichino@mt'</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">user</span>    = configu<span style="color: black;">&#91;</span><span style="color: #483d8b;">'user'</span><span style="color: black;">&#93;</span>
passwd  = config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'pass'</span><span style="color: black;">&#93;</span>
post    = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'title'</span>        : <span style="color: #483d8b;">'title from xmlrpc'</span>,
           <span style="color: #483d8b;">'description'</span>  : <span style="color: #483d8b;">'this is a body and custom'</span>,
           <span style="color: #483d8b;">'dateCreated'</span>  : <span style="color: #483d8b;">'2010-01-01'</span>,
           <span style="color: #483d8b;">'mt_keywords'</span>  : <span style="color: #483d8b;">'test, sample'</span>,
           <span style="color: #483d8b;">'mt_text_more'</span> : <span style="color: #483d8b;">'item1=abc'</span><span style="color: black;">&#125;</span>
publish = <span style="color: #008000;">False</span>
api = <span style="color: #dc143c;">xmlrpclib</span>.<span style="color: black;">ServerProxy</span><span style="color: black;">&#40;</span>api_url<span style="color: black;">&#41;</span>
api.<span style="color: black;">metaWeblog</span>.<span style="color: black;">newPost</span><span style="color: black;">&#40;</span>blog_id, <span style="color: #dc143c;">user</span>, passwd, post, publish<span style="color: black;">&#41;</span></pre></div></div>

<p>以上で一応は記事の投稿ができましたが、投稿された記事を確認してみるとまだ問題があります。それはpublishをFalseにしているにも関わらず、投稿された記事が公開状態になっている事です。調べてみると、現バージョンのMTではpublishしないというのは再構築しないという意味で、公開せずに下書き状態にするという意味ではないようです。何とかならないかと調べてみると、mt-config.cgiに以下の設定を加える事で、publishがFalseの場合は下書き状態にできる事がわかりました。</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;"># mt-config.cgiに以下を追加
&nbsp;
NoPublishMeansDraft 1</pre></div></div>

<p>これで無事にXML-RPC経由で投稿した記事が下書きで保存されます。他にも基本的なAPIはほぼ実装されていて、画像をアップロードしたり、記事を再構築したりというのができて便利なのですが、APIの仕様が汎用的な事もあり細かいところには手が届きません。(例えばアップロードした画像のasset idなどは取得できません) なので現時点で本気で外部からMTを制御する場合はXML-RPCインターフェースに加えてmechanizeなどのやや強引な手段も必要になるような気がします。</p>
]]></content:encoded>
			<wfw:commentRss>http://taichino.com/memo/2045/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hello Cython World</title>
		<link>http://taichino.com/programming/2005</link>
		<comments>http://taichino.com/programming/2005#comments</comments>
		<pubDate>Sun, 24 Oct 2010 05:05:42 +0000</pubDate>
		<dc:creator>taichino</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[cython]]></category>

		<guid isPermaLink="false">http://taichino.com/?p=2005</guid>
		<description><![CDATA[lxmlのソースを読もうとしたらcythonというPythonの拡張を書くためのPythonとCの間の子みたいな言語で書かれているという事で、全く知らないままだとlxmlのソースに挑む気が起こらなかったので少し調べてみました。まぁ調べてみたといってもcythonのドキュメントの最初に書かれているGetting Startedを舐めただけなんですけども。 まずcythonをインストールします。 $ easy_install cython そして恒例のhello worldは以下になります。拡張子は.pyxを使うようです。 # hello.pyx def say_hello_to&#40;name&#41;: print 'Hello %s' % name どう見てもPythonのコードなので楽勝なのですが、これを使えるようにsetup.pyを書かねばなりません。少しだけ面倒ですね。以下のように基本は通常のsetup.pyですが、cmdclassにbuild_extを指定する必要があります。 from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext &#160; ext_modules = &#91;Extension&#40;'hello', &#91;'hello.pyx'&#93;&#41;&#93; # hello.pyxファイルからhelloモジュールを登録する setup&#40; name = 'Hello world app', cmdclass = &#123;'build_ext':build_ext&#125;, ext_modules = ext_modules &#41; 続いてsetup.pyを使ってビルドしてみます。そうするとhello.cとbuildディレクトリが作成されます。ちらっとだけhello.cを見てみましたが、1263行もあったのでそっとファイルを閉じました。 $ python setup.py build_ext [...]]]></description>
			<content:encoded><![CDATA[<p>lxmlのソースを読もうとしたらcythonというPythonの拡張を書くためのPythonとCの間の子みたいな言語で書かれているという事で、全く知らないままだとlxmlのソースに挑む気が起こらなかったので少し調べてみました。まぁ調べてみたといっても<a href="http://docs.cython.org/">cythonのドキュメント</a>の最初に書かれている<a href="http://docs.cython.org/src/quickstart/index.html">Getting Started</a>を舐めただけなんですけども。</p>
<p><span id="more-2005"></span></p>
<p>まずcythonをインストールします。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ easy_install cython</pre></div></div>

<p>そして恒例のhello worldは以下になります。拡張子は.pyxを使うようです。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># hello.pyx</span>
<span style="color: #ff7700;font-weight:bold;">def</span> say_hello_to<span style="color: black;">&#40;</span>name<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Hello %s'</span> <span style="color: #66cc66;">%</span> name</pre></div></div>

<p>どう見てもPythonのコードなので楽勝なのですが、これを使えるようにsetup.pyを書かねばなりません。少しだけ面倒ですね。以下のように基本は通常のsetup.pyですが、cmdclassにbuild_extを指定する必要があります。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">distutils</span>.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> setup
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">distutils</span>.<span style="color: black;">extension</span> <span style="color: #ff7700;font-weight:bold;">import</span> Extension
<span style="color: #ff7700;font-weight:bold;">from</span> Cython.<span style="color: black;">Distutils</span> <span style="color: #ff7700;font-weight:bold;">import</span> build_ext
&nbsp;
ext_modules = <span style="color: black;">&#91;</span>Extension<span style="color: black;">&#40;</span><span style="color: #483d8b;">'hello'</span>, <span style="color: black;">&#91;</span><span style="color: #483d8b;">'hello.pyx'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>   <span style="color: #808080; font-style: italic;"># hello.pyxファイルからhelloモジュールを登録する</span>
setup<span style="color: black;">&#40;</span>
  name        = <span style="color: #483d8b;">'Hello world app'</span>,
  cmdclass    = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'build_ext'</span>:build_ext<span style="color: black;">&#125;</span>,
  ext_modules = ext_modules
<span style="color: black;">&#41;</span></pre></div></div>

<p>続いてsetup.pyを使ってビルドしてみます。そうするとhello.cとbuildディレクトリが作成されます。ちらっとだけhello.cを見てみましたが、1263行もあったのでそっとファイルを閉じました。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ python setup.py build_ext
$ <span style="color: #c20cb9; font-weight: bold;">ls</span>
build           hello.c         hello.pyx       setup.py</pre></div></div>

<p>ビルドが成功したら早速インストールします。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ python setup.py install_lib</pre></div></div>

<p>これで通常のpythonモジュールと同様にimportして実装した機能を使う事ができます。簡単ですね。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">from</span> hello <span style="color: #ff7700;font-weight:bold;">import</span> say_hello_to
<span style="color: #66cc66;">&gt;&gt;&gt;</span> say_hello_to<span style="color: black;">&#40;</span><span style="color: #483d8b;">'taichino'</span><span style="color: black;">&#41;</span>
Hello taichino</pre></div></div>

<p>さて上記のようにpure pythonと同様のコードで拡張機能を書いても良いのですが(コンパイルされる分高速)、どうせCythonを使って拡張機能を実装するのであれば、高速化のためにCython独自の構文を使った方が良いようです。</p>
<p>以下のコードが次のサンプルになります。型とcdefやらcpdefといった呼び出し規約の明示を行っています。ついでにmathライブラリの機能も使っていますね。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">cdef extern <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #483d8b;">&quot;math.h&quot;</span>:
  double sin<span style="color: black;">&#40;</span>double<span style="color: black;">&#41;</span>
&nbsp;
cpdef double func1<span style="color: black;">&#40;</span>double x<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">return</span> sin<span style="color: black;">&#40;</span>x<span style="color: #66cc66;">*</span>x<span style="color: black;">&#41;</span>
&nbsp;
cpdef double func2<span style="color: black;">&#40;</span>double x<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">return</span> x<span style="color: #66cc66;">**</span><span style="color: #ff4500;">2</span>-x</pre></div></div>

<p>外部ライブラリを利用する場合はsetup.pyにリンク情報を明示する必要があるようです。ビルドとインストールは先ほどと同じ手順になります。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">distutils</span>.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> setup
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">distutils</span>.<span style="color: black;">extension</span> <span style="color: #ff7700;font-weight:bold;">import</span> Extension
<span style="color: #ff7700;font-weight:bold;">from</span> Cython.<span style="color: black;">Distutils</span> <span style="color: #ff7700;font-weight:bold;">import</span> build_ext
&nbsp;
ext_modules=<span style="color: black;">&#91;</span>
  Extension<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sample&quot;</span>,
            <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;cython_func.pyx&quot;</span><span style="color: black;">&#93;</span>,
            libraries=<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;m&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
&nbsp;
setup<span style="color: black;">&#40;</span>
  name = <span style="color: #483d8b;">&quot;sample&quot;</span>,
  cmdclass = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;build_ext&quot;</span>: build_ext<span style="color: black;">&#125;</span>,
  ext_modules = ext_modules
<span style="color: black;">&#41;</span></pre></div></div>

<p>折角なのでベンチマークを取ってみました。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">math</span>
<span style="color: #ff7700;font-weight:bold;">from</span> benchmarker <span style="color: #ff7700;font-weight:bold;">import</span> Benchmarker
<span style="color: #ff7700;font-weight:bold;">import</span> sample
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> func1<span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">math</span>.<span style="color: black;">sin</span><span style="color: black;">&#40;</span>x<span style="color: #66cc66;">*</span>x<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> func2<span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">return</span> x<span style="color: #66cc66;">**</span><span style="color: #ff4500;">2</span>-x
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
  num = <span style="color: #ff4500;">50000</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># func1</span>
  bm  = Benchmarker<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  <span style="color: #808080; font-style: italic;"># pure python code</span>
  <span style="color: #ff7700;font-weight:bold;">with</span> bm<span style="color: black;">&#40;</span><span style="color: #483d8b;">'pure python'</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>num<span style="color: black;">&#41;</span>:
      func1<span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>
  <span style="color: #808080; font-style: italic;"># cython code</span>
  <span style="color: #ff7700;font-weight:bold;">with</span> bm<span style="color: black;">&#40;</span><span style="color: #483d8b;">'cython'</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>num<span style="color: black;">&#41;</span>:
      sample.<span style="color: black;">func1</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>
  bm.<span style="color: black;">print_compared_matrix</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># func2</span>
  bm = Benchmarker<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">with</span> bm<span style="color: black;">&#40;</span><span style="color: #483d8b;">'pure python'</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>num<span style="color: black;">&#41;</span>:
      func2<span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">with</span> bm<span style="color: black;">&#40;</span><span style="color: #483d8b;">'cython'</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>num<span style="color: black;">&#41;</span>:
      sample.<span style="color: black;">func2</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>
  bm.<span style="color: black;">print_compared_matrix</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>: main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>結果は以下のようになりました。まぁ速いには速いけどそこまで劇的でもない印象です。関数呼び出しのコストが高いみたいなので、Cライブラリを呼び出すなどして纏まった処理単位をラップすると効果が高そうですね。</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">                                  utime     stime     total      real
pure python                       0.050     0.000     0.050     0.028
cython                            0.017     0.000     0.017     0.014
-------------------------------------------------------------------------------
                        real      [01]     [02]
[01] pure python      0.028s        -    -50.6%
[02]      cython      0.014s    102.5%       - 
                                  utime     stime     total      real
pure python                       0.017     0.000     0.017     0.016
cython                            0.017     0.000     0.017     0.011
-------------------------------------------------------------------------------
                        real      [01]     [02]
[01] pure python      0.016s        -    -33.7%
[02]      cython      0.011s     50.8%       -</pre></div></div>

<p>という事でイカツそうなCythonがほとんどPythonと同じで、怖くない事がわかったので、早速lxmlのコード解析に着手したいと思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://taichino.com/programming/2005/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pythonで実行時間とメモリの測定をする</title>
		<link>http://taichino.com/programming/1972</link>
		<comments>http://taichino.com/programming/1972#comments</comments>
		<pubDate>Sun, 03 Oct 2010 11:05:30 +0000</pubDate>
		<dc:creator>taichino</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[beautifulsoup]]></category>
		<category><![CDATA[benchmarker]]></category>
		<category><![CDATA[guppy]]></category>
		<category><![CDATA[lxml]]></category>

		<guid isPermaLink="false">http://taichino.com/?p=1972</guid>
		<description><![CDATA[しばらくベンチマークコードを書いてなくてすっかり忘れていたので、メモ書きです。今回は例題として、yahooのこのページをBeautifulSoupとlxmlでのスクレイピング比較をしてみる事にしました。比較対象の関数は以下の通りです。どちらのコードも入力・出力ともに同じなので、どちらが実行時間やメモリ使用量が少ないのかを知りたくなりますね。 # BeautifulSoup def scrape_with_bs&#40;html&#41;: from BeautifulSoup import BeautifulSoup soup = BeautifulSoup&#40;html&#41; rows = soup.find&#40;'table', attrs=&#123;'class':'channel9'&#125;&#41;.findAll&#40;'tr'&#41; channels = rows&#91;0&#93;.findAll&#40;'td', attrs=&#123;'class':'station'&#125;&#41; programs = rows&#91;1&#93;.findAll&#40;'td', attrs=&#123;'class':'turnup'&#125;&#41; res = &#91;&#93; for ch, prog in zip&#40;channels, programs&#41;: res.append&#40;&#40;ch.find&#40;'span'&#41;.string, ch.find&#40;'a'&#41;.string, prog.find&#40;'a'&#41;.string&#41;&#41; return res &#160; # lxml def scrape_with_lxml&#40;html&#41;: import lxml.html root = lxml.html.fromstring&#40;html.decode&#40;'utf-8'&#41;&#41; rows = root.xpath&#40;'//table[@class=&#34;channel9&#34;]/tr'&#41; channels = rows&#91;0&#93;.xpath&#40;'td[@class=&#34;station&#34;]'&#41; programs [...]]]></description>
			<content:encoded><![CDATA[<p>しばらくベンチマークコードを書いてなくてすっかり忘れていたので、メモ書きです。今回は例題として、<a href="http://tv.yahoo.co.jp/listings/realtime/">yahooのこのページ</a>をBeautifulSoupとlxmlでのスクレイピング比較をしてみる事にしました。比較対象の関数は以下の通りです。どちらのコードも入力・出力ともに同じなので、どちらが実行時間やメモリ使用量が少ないのかを知りたくなりますね。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># BeautifulSoup</span>
<span style="color: #ff7700;font-weight:bold;">def</span> scrape_with_bs<span style="color: black;">&#40;</span>html<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">from</span> BeautifulSoup <span style="color: #ff7700;font-weight:bold;">import</span> BeautifulSoup  
  soup = BeautifulSoup<span style="color: black;">&#40;</span>html<span style="color: black;">&#41;</span>
  rows = soup.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'table'</span>, attrs=<span style="color: black;">&#123;</span><span style="color: #483d8b;">'class'</span>:<span style="color: #483d8b;">'channel9'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>.<span style="color: black;">findAll</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'tr'</span><span style="color: black;">&#41;</span>
  channels = rows<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">findAll</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'td'</span>, attrs=<span style="color: black;">&#123;</span><span style="color: #483d8b;">'class'</span>:<span style="color: #483d8b;">'station'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
  programs = rows<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">findAll</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'td'</span>, attrs=<span style="color: black;">&#123;</span><span style="color: #483d8b;">'class'</span>:<span style="color: #483d8b;">'turnup'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
  res = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
  <span style="color: #ff7700;font-weight:bold;">for</span> ch, prog <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">zip</span><span style="color: black;">&#40;</span>channels, programs<span style="color: black;">&#41;</span>:
    res.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>ch.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'span'</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">string</span>, ch.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'a'</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">string</span>, prog.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'a'</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">string</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> res
&nbsp;
<span style="color: #808080; font-style: italic;"># lxml</span>
<span style="color: #ff7700;font-weight:bold;">def</span> scrape_with_lxml<span style="color: black;">&#40;</span>html<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">import</span> lxml.<span style="color: black;">html</span>
  root = lxml.<span style="color: black;">html</span>.<span style="color: black;">fromstring</span><span style="color: black;">&#40;</span>html.<span style="color: black;">decode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'utf-8'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  rows = root.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'//table[@class=&quot;channel9&quot;]/tr'</span><span style="color: black;">&#41;</span>
  channels = rows<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'td[@class=&quot;station&quot;]'</span><span style="color: black;">&#41;</span>
  programs = rows<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'td[@class=&quot;turnup&quot;]'</span><span style="color: black;">&#41;</span>
  res = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
  <span style="color: #ff7700;font-weight:bold;">for</span> ch, prog <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">zip</span><span style="color: black;">&#40;</span>channels, programs<span style="color: black;">&#41;</span>:
    res.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>ch.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'span/text()'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, \
          ch.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'descendant::a/text()'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, \
          prog.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'descendant::a/text()'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> res</pre></div></div>

<p>ちなみに上記の関数から得られる配列をprettyprintすると、以下の様な出力が得られます。各チャンネルごとに、今放送中の番組を取得しています。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: black;">&#91;</span>
    <span style="color: black;">&#91;</span>
        <span style="color: #483d8b;">&quot;アナログ1ch&quot;</span>, 
        <span style="color: #483d8b;">&quot;ＮＨＫ総合&quot;</span>, 
        <span style="color: #483d8b;">&quot;ニュース&quot;</span>
    <span style="color: black;">&#93;</span>, 
    <span style="color: black;">&#91;</span>
        <span style="color: #483d8b;">&quot;アナログ3ch&quot;</span>, 
        <span style="color: #483d8b;">&quot;ＮＨＫ教育&quot;</span>, 
        <span style="color: #483d8b;">&quot;ハーバード白熱教室＠東京大学「イチローの年俸は...&quot;</span>
    <span style="color: black;">&#93;</span>, 
    <span style="color: black;">&#91;</span>
        <span style="color: #483d8b;">&quot;アナログ4ch&quot;</span>, 
        <span style="color: #483d8b;">&quot;日本テレビ&quot;</span>, 
        <span style="color: #483d8b;">&quot;真相報道　バンキシャ!&quot;</span>
    <span style="color: black;">&#93;</span>, 
    <span style="color: black;">&#91;</span>
        <span style="color: #483d8b;">&quot;アナログ6ch&quot;</span>, 
        <span style="color: #483d8b;">&quot;ＴＢＳ&quot;</span>, 
        <span style="color: #483d8b;">&quot;THE世界遺産「皇帝たちの地下宮殿」〜...&quot;</span>
    <span style="color: black;">&#93;</span>, 
    <span style="color: black;">&#91;</span>
        <span style="color: #483d8b;">&quot;アナログ8ch&quot;</span>, 
        <span style="color: #483d8b;">&quot;フジテレビ&quot;</span>, 
        <span style="color: #483d8b;">&quot;笑顔がごちそう　ウチゴハン&quot;</span>
    <span style="color: black;">&#93;</span>, 
    <span style="color: black;">&#91;</span>
        <span style="color: #483d8b;">&quot;アナログ10ch&quot;</span>, 
        <span style="color: #483d8b;">&quot;テレビ朝日&quot;</span>, 
        <span style="color: #483d8b;">&quot;ドライブ　A　GO!GO!「群馬格安温...&quot;</span>
    <span style="color: black;">&#93;</span>, 
    <span style="color: black;">&#91;</span>
        <span style="color: #483d8b;">&quot;アナログ12ch&quot;</span>, 
        <span style="color: #483d8b;">&quot;テレビ東京&quot;</span>, 
        <span style="color: #483d8b;">&quot;TOKYO　...&quot;</span>
    <span style="color: black;">&#93;</span>, 
    <span style="color: black;">&#91;</span>
        <span style="color: #483d8b;">&quot;アナログ14ch&quot;</span>, 
        <span style="color: #483d8b;">&quot;TOKYO MX&quot;</span>, 
        <span style="color: #483d8b;">&quot;芸術史と芸術理論( 10)第1回◇放送...&quot;</span>
    <span style="color: black;">&#93;</span>
<span style="color: black;">&#93;</span></pre></div></div>

<p><span id="more-1972"></span><br />
さて、いきなり結論になりますが、書いたコードが以下になります。時間計測にtimeit、メモリ計測に<a href="http://pypi.python.org/pypi/guppy/">guppy</a>をそれぞれ使用しています。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">timeit</span>
<span style="color: #ff7700;font-weight:bold;">from</span> guppy <span style="color: #ff7700;font-weight:bold;">import</span> hpy
<span style="color: #ff7700;font-weight:bold;">from</span> prettyprint <span style="color: #ff7700;font-weight:bold;">import</span> pp
&nbsp;
<span style="color: #808080; font-style: italic;"># BeautifulSoup</span>
<span style="color: #ff7700;font-weight:bold;">def</span> scrape_with_bs<span style="color: black;">&#40;</span>html<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">from</span> BeautifulSoup <span style="color: #ff7700;font-weight:bold;">import</span> BeautifulSoup  
  soup = BeautifulSoup<span style="color: black;">&#40;</span>html<span style="color: black;">&#41;</span>
  rows = soup.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'table'</span>, attrs=<span style="color: black;">&#123;</span><span style="color: #483d8b;">'class'</span>:<span style="color: #483d8b;">'channel9'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>.<span style="color: black;">findAll</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'tr'</span><span style="color: black;">&#41;</span>
  channels = rows<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">findAll</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'td'</span>, attrs=<span style="color: black;">&#123;</span><span style="color: #483d8b;">'class'</span>:<span style="color: #483d8b;">'station'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
  programs = rows<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">findAll</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'td'</span>, attrs=<span style="color: black;">&#123;</span><span style="color: #483d8b;">'class'</span>:<span style="color: #483d8b;">'turnup'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
  res = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
  <span style="color: #ff7700;font-weight:bold;">for</span> ch, prog <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">zip</span><span style="color: black;">&#40;</span>channels, programs<span style="color: black;">&#41;</span>:
    res.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>ch.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'span'</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">string</span>, ch.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'a'</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">string</span>, prog.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'a'</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">string</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> res
&nbsp;
<span style="color: #808080; font-style: italic;"># lxml</span>
<span style="color: #ff7700;font-weight:bold;">def</span> scrape_with_lxml<span style="color: black;">&#40;</span>html<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">import</span> lxml.<span style="color: black;">html</span>
  root = lxml.<span style="color: black;">html</span>.<span style="color: black;">fromstring</span><span style="color: black;">&#40;</span>html.<span style="color: black;">decode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'utf-8'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  rows = root.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'//table[@class=&quot;channel9&quot;]/tr'</span><span style="color: black;">&#41;</span>
  channels = rows<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'td[@class=&quot;station&quot;]'</span><span style="color: black;">&#41;</span>
  programs = rows<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'td[@class=&quot;turnup&quot;]'</span><span style="color: black;">&#41;</span>
  res = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
  <span style="color: #ff7700;font-weight:bold;">for</span> ch, prog <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">zip</span><span style="color: black;">&#40;</span>channels, programs<span style="color: black;">&#41;</span>:
    res.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>ch.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'span/text()'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, \
          ch.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'descendant::a/text()'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, \
          prog.<span style="color: black;">xpath</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'descendant::a/text()'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> res
&nbsp;
<span style="color: #808080; font-style: italic;"># load target html</span>
<span style="color: #ff7700;font-weight:bold;">def</span> load<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>
  url = <span style="color: #483d8b;">'http://tv.yahoo.co.jp/listings/realtime/'</span>
  html = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> html.<span style="color: black;">decode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'euc_jp'</span>, <span style="color: #483d8b;">'ignore'</span><span style="color: black;">&#41;</span>.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'utf-8'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
  func_name = <span style="color: #483d8b;">'scrape_with_lxml'</span> <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">'lxml'</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: #483d8b;">'scrape_with_bs'</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># load data to scrape</span>
  html = load<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># measure time </span>
  setup = \
<span style="color: #483d8b;">&quot;&quot;&quot;
from __main__ import load, %s
html=load()
&quot;&quot;&quot;</span> <span style="color: #66cc66;">%</span> func_name
  timer = <span style="color: #dc143c;">timeit</span>.<span style="color: black;">Timer</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s(html)'</span> <span style="color: #66cc66;">%</span> func_name, setup<span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># print result</span>
  <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'%s result %f'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>func_name, timer.<span style="color: #dc143c;">timeit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  hp = hpy<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">print</span> hp.<span style="color: black;">heap</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>: main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>また実行結果は以下の通りです。実行時間とメモリ使用量がとれていますね。本筋から外れますが、なんと実行速度に100倍近い差が出てます。メモリ使用量でもlxmlの方が少ないので、流石にlxmlの方が早いかな位で思ってたんですが、ここまで違うとは思いませんでした。lxml使える場合はlxml一択な雰囲気です。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ python bm_test.py bs    <span style="color: #666666; font-style: italic;"># まずはBeautifulSoup</span>
scrape_with_bs result <span style="color: #000000;">29.445319</span>
Partition of a <span style="color: #000000; font-weight: bold;">set</span> of <span style="color: #000000;">96041</span> objects. Total <span style="color: #c20cb9; font-weight: bold;">size</span> = <span style="color: #000000;">4762520</span> bytes.
 Index  Count   <span style="color: #000000; font-weight: bold;">%</span>     Size   <span style="color: #000000; font-weight: bold;">%</span> Cumulative  <span style="color: #000000; font-weight: bold;">%</span> Kind <span style="color: #7a0874; font-weight: bold;">&#40;</span>class <span style="color: #000000; font-weight: bold;">/</span> dict of class<span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #000000;">0</span>  <span style="color: #000000;">24263</span>  <span style="color: #000000;">25</span>  <span style="color: #000000;">1831800</span>  <span style="color: #000000;">38</span>   <span style="color: #000000;">1831800</span>  <span style="color: #000000;">38</span> str
     <span style="color: #000000;">1</span>  <span style="color: #000000;">10210</span>  <span style="color: #000000;">11</span>   <span style="color: #000000;">785056</span>  <span style="color: #000000;">16</span>   <span style="color: #000000;">2616856</span>  <span style="color: #000000;">55</span> tuple
     <span style="color: #000000;">2</span>  <span style="color: #000000;">50129</span>  <span style="color: #000000;">52</span>   <span style="color: #000000;">601548</span>  <span style="color: #000000;">13</span>   <span style="color: #000000;">3218404</span>  <span style="color: #000000;">68</span> int
     <span style="color: #000000;">3</span>    <span style="color: #000000;">490</span>   <span style="color: #000000;">1</span>   <span style="color: #000000;">256760</span>   <span style="color: #000000;">5</span>   <span style="color: #000000;">3475164</span>  <span style="color: #000000;">73</span> dict <span style="color: #7a0874; font-weight: bold;">&#40;</span>no owner<span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #000000;">4</span>    <span style="color: #000000;">157</span>   <span style="color: #000000;">0</span>   <span style="color: #000000;">226268</span>   <span style="color: #000000;">5</span>   <span style="color: #000000;">3701432</span>  <span style="color: #000000;">78</span> dict of module
     <span style="color: #000000;">5</span>   <span style="color: #000000;">2420</span>   <span style="color: #000000;">3</span>   <span style="color: #000000;">164560</span>   <span style="color: #000000;">3</span>   <span style="color: #000000;">3865992</span>  <span style="color: #000000;">81</span> types.CodeType
     <span style="color: #000000;">6</span>   <span style="color: #000000;">2338</span>   <span style="color: #000000;">2</span>   <span style="color: #000000;">140280</span>   <span style="color: #000000;">3</span>   <span style="color: #000000;">4006272</span>  <span style="color: #000000;">84</span> <span style="color: #000000; font-weight: bold;">function</span>
     <span style="color: #000000;">7</span>    <span style="color: #000000;">296</span>   <span style="color: #000000;">0</span>   <span style="color: #000000;">131680</span>   <span style="color: #000000;">3</span>   <span style="color: #000000;">4137952</span>  <span style="color: #000000;">87</span> dict of <span style="color: #7a0874; font-weight: bold;">type</span>
     <span style="color: #000000;">8</span>    <span style="color: #000000;">296</span>   <span style="color: #000000;">0</span>   <span style="color: #000000;">128908</span>   <span style="color: #000000;">3</span>   <span style="color: #000000;">4266860</span>  <span style="color: #000000;">90</span> <span style="color: #7a0874; font-weight: bold;">type</span>
     <span style="color: #000000;">9</span>    <span style="color: #000000;">209</span>   <span style="color: #000000;">0</span>   <span style="color: #000000;">104524</span>   <span style="color: #000000;">2</span>   <span style="color: #000000;">4371384</span>  <span style="color: #000000;">92</span> dict of class
<span style="color: #000000; font-weight: bold;">&amp;</span>lt;<span style="color: #000000;">112</span> <span style="color: #c20cb9; font-weight: bold;">more</span> rows. Type e.g. <span style="color: #ff0000;">'_.more'</span> to view.<span style="color: #000000; font-weight: bold;">&gt;</span>
&nbsp;
$ python bm_test.py lxml  <span style="color: #666666; font-style: italic;"># 次にlxml</span>
scrape_with_lxml result <span style="color: #000000;">0.399702</span>
Partition of a <span style="color: #000000; font-weight: bold;">set</span> of <span style="color: #000000;">62306</span> objects. Total <span style="color: #c20cb9; font-weight: bold;">size</span> = <span style="color: #000000;">4553468</span> bytes.
 Index  Count   <span style="color: #000000; font-weight: bold;">%</span>     Size   <span style="color: #000000; font-weight: bold;">%</span> Cumulative  <span style="color: #000000; font-weight: bold;">%</span> Kind <span style="color: #7a0874; font-weight: bold;">&#40;</span>class <span style="color: #000000; font-weight: bold;">/</span> dict of class<span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #000000;">0</span>  <span style="color: #000000;">26190</span>  <span style="color: #000000;">42</span>  <span style="color: #000000;">1991864</span>  <span style="color: #000000;">44</span>   <span style="color: #000000;">1991864</span>  <span style="color: #000000;">44</span> str
     <span style="color: #000000;">1</span>  <span style="color: #000000;">10939</span>  <span style="color: #000000;">18</span>   <span style="color: #000000;">480916</span>  <span style="color: #000000;">11</span>   <span style="color: #000000;">2472780</span>  <span style="color: #000000;">54</span> tuple
     <span style="color: #000000;">2</span>    <span style="color: #000000;">498</span>   <span style="color: #000000;">1</span>   <span style="color: #000000;">272472</span>   <span style="color: #000000;">6</span>   <span style="color: #000000;">2745252</span>  <span style="color: #000000;">60</span> dict <span style="color: #7a0874; font-weight: bold;">&#40;</span>no owner<span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #000000;">3</span>    <span style="color: #000000;">135</span>   <span style="color: #000000;">0</span>   <span style="color: #000000;">227796</span>   <span style="color: #000000;">5</span>   <span style="color: #000000;">2973048</span>  <span style="color: #000000;">65</span> dict of module
     <span style="color: #000000;">4</span>    <span style="color: #000000;">459</span>   <span style="color: #000000;">1</span>   <span style="color: #000000;">199124</span>   <span style="color: #000000;">4</span>   <span style="color: #000000;">3172172</span>  <span style="color: #000000;">70</span> <span style="color: #7a0874; font-weight: bold;">type</span>
     <span style="color: #000000;">5</span>    <span style="color: #000000;">459</span>   <span style="color: #000000;">1</span>   <span style="color: #000000;">184068</span>   <span style="color: #000000;">4</span>   <span style="color: #000000;">3356240</span>  <span style="color: #000000;">74</span> dict of <span style="color: #7a0874; font-weight: bold;">type</span>
     <span style="color: #000000;">6</span>   <span style="color: #000000;">2599</span>   <span style="color: #000000;">4</span>   <span style="color: #000000;">176732</span>   <span style="color: #000000;">4</span>   <span style="color: #000000;">3532972</span>  <span style="color: #000000;">78</span> types.CodeType
     <span style="color: #000000;">7</span>   <span style="color: #000000;">1836</span>   <span style="color: #000000;">3</span>   <span style="color: #000000;">149512</span>   <span style="color: #000000;">3</span>   <span style="color: #000000;">3682484</span>  <span style="color: #000000;">81</span> unicode
     <span style="color: #000000;">8</span>   <span style="color: #000000;">2491</span>   <span style="color: #000000;">4</span>   <span style="color: #000000;">149460</span>   <span style="color: #000000;">3</span>   <span style="color: #000000;">3831944</span>  <span style="color: #000000;">84</span> <span style="color: #000000; font-weight: bold;">function</span>
     <span style="color: #000000;">9</span>    <span style="color: #000000;">184</span>   <span style="color: #000000;">0</span>   <span style="color: #000000;">122528</span>   <span style="color: #000000;">3</span>   <span style="color: #000000;">3954472</span>  <span style="color: #000000;">87</span> dict of class
<span style="color: #000000; font-weight: bold;">&amp;</span>lt;<span style="color: #000000;">137</span> <span style="color: #c20cb9; font-weight: bold;">more</span> rows. Type e.g. <span style="color: #ff0000;">'_.more'</span> to view.<span style="color: #000000; font-weight: bold;">&gt;</span></pre></div></div>

<p>以上でとりあえずBenchmarkが取れます。ところが今までは不満に感じなかったのですが、流石にtimeitは不便すぎると思います。文字列で測定対象のコード渡すなんてインデント崩れてコードは汚くなるし、比較も簡単に出来ません。幾ら何でもこれはないです。Perlで言うところのtimetheseやcmptheseは無いの？と思って調べてみたら、<a href="http://pypi.python.org/pypi/Benchmarker/">Benchmarker</a>モジュールが見つかりました。これを使えばcmptheseのノリで実行時間の測定、比較ができます。</p>
<p>使い方は簡単で、withブロックの中に測定したいコードを書いて、print_compared_matrixを呼ぶだけです。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> benchmarker <span style="color: #ff7700;font-weight:bold;">import</span> Benchmarker
&nbsp;
<span style="color: #808080; font-style: italic;"># 測定対象のコードなどは上記と同じです。</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> cmp_with_benchmark<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
  html = load<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
  bm = Benchmarker<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  <span style="color: #808080; font-style: italic;"># BeautifulSoupの測定コード</span>
  <span style="color: #ff7700;font-weight:bold;">with</span> bm<span style="color: black;">&#40;</span><span style="color: #483d8b;">'BeautifulSoup'</span><span style="color: black;">&#41;</span>:
    scrape_with_bs<span style="color: black;">&#40;</span>html<span style="color: black;">&#41;</span>
  <span style="color: #808080; font-style: italic;"># lxmlの測定コード</span>
  <span style="color: #ff7700;font-weight:bold;">with</span> bm<span style="color: black;">&#40;</span><span style="color: #483d8b;">'lxml'</span><span style="color: black;">&#41;</span>:
    scrape_with_lxml<span style="color: black;">&#40;</span>html<span style="color: black;">&#41;</span>
&nbsp;
  bm.<span style="color: black;">print_compared_matrix</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>すると以下の様な結果が得られます。これこそ欲しかった結果ですね。コードもすっきりしていますし、比較も簡単です。ついでにメモリの測定についてももう少し便利なモジュールが無いか探してみたのですが、見つかりませんでした。ご存知の方がおられましたら教えて下さい。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">                                  utime     stime     total      real
BeautifulSoup                     <span style="color: #000000;">5.200</span>     <span style="color: #000000;">0.183</span>     <span style="color: #000000;">5.383</span>     <span style="color: #000000;">3.242</span>
lxml                              <span style="color: #000000;">0.100</span>     <span style="color: #000000;">0.033</span>     <span style="color: #000000;">0.133</span>     <span style="color: #000000;">0.086</span>
<span style="color: #660033;">-------------------------------------------------------------------------------</span>
                          real      <span style="color: #7a0874; font-weight: bold;">&#91;</span>01<span style="color: #7a0874; font-weight: bold;">&#93;</span>     <span style="color: #7a0874; font-weight: bold;">&#91;</span>02<span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>01<span style="color: #7a0874; font-weight: bold;">&#93;</span> BeautifulSoup      3.242s        -    -<span style="color: #000000;">97.4</span><span style="color: #000000; font-weight: bold;">%</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>02<span style="color: #7a0874; font-weight: bold;">&#93;</span>          lxml      0.086s   <span style="color: #000000;">3691.9</span><span style="color: #000000; font-weight: bold;">%</span>       -</pre></div></div>

<p>長くなりましたが、以下がまとめになります。</p>
<ul>
<li><strong>実行時間測定にtimeitは使いづらいので<font style="color:red">benchmarker</font></strong></li>
<li><strong>メモリ使用量測定にguppy。でももっと良いモジュールないの？</strong></li>
<li><strong><font style="color:red">lxml速すぎワロタ</font></strong></li>
</ul>
<p>なお100倍近い差が出ている上記測定結果はPython2.5.4上でのもので、Python2.6.1だとBeautifulSoupとlxmlの差は15倍程度でした。Python2.7.x、Python3.xではもっと速くなっているかもしれません。</p>
]]></content:encoded>
			<wfw:commentRss>http://taichino.com/programming/1972/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

