<?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; import</title>
	<atom:link href="http://taichino.com/tag/import/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>Pythonで動的にクラスをロードしたい件</title>
		<link>http://taichino.com/programming/1478</link>
		<comments>http://taichino.com/programming/1478#comments</comments>
		<pubDate>Thu, 07 Jan 2010 01:04:54 +0000</pubDate>
		<dc:creator>taichino</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[import]]></category>

		<guid isPermaLink="false">http://taichino.com/?p=1478</guid>
		<description><![CDATA[app-engine-patchを使っていて、settings.pyに記述されているAUTH_USER_MODELクラスを動的にロードしたかったんですが、簡単に方法が解らなかったのでメモしておきます。要はクラス名が文字列で与えられている場合に、そのクラスにアクセスしたいという話です。 まず対象のクラスが既にimportされている状態であれば、組込み関数のglobalsを使えます。 class Hoge: pass hoge_klass = globals&#40;&#41;&#91;'Hoge'&#93; hoge_instance = hoge_klass&#40;&#41; しかし設定ファイルに書かれているクラスをロードするケースでは、対象クラスがimportされていない事も多いと思います。そこでクラスを動的にimportしたい訳ですが、僕が調べた限りでは、一旦クラスが属しているモジュールをimportし、そのモジュールからクラスを得るという手順が必要なようです。モジュールからクラスの取得にはgetattrを使います。コードとしては以下になります。 path_to_class = 'package.module.class_name' # このクラスをロードしたい target = path_to_class.split&#40;'.'&#41; &#40;package, module, cls_name&#41; = &#40;target&#91;0&#93;, '.'.join&#40;target&#91;:-1&#93;&#41;, target&#91;-1&#93;&#41; &#160; # __import__したモジュールからcls_nameクラスを取得 klass = getattr&#40;__import__&#40;module, fromlist=&#91;package&#93;&#41;, cls_name&#41; klass_instance = klass&#40;&#41; クラスへの絶対パスからpackage名, module名, class名に分解して, __import__, getattrで使用しています。ここで注意したいのは__import__のfromlistにパッケージを指定する必要がある事です。fromlistが指定されないと、例えばpackage.moduleを指定しても期待したmoduleではなく、packageモジュールが返却されます。リファレンスに書かれているのですが、読み落としてしまいハマりました。 ということで一応上記の方法でパスが与えられたクラスをロードできますが、モジュールを介しているのが気持ち悪いです。やりたい事は from package.module import class_name なので、__import__とかで一発で出来そうですが、探せませんでした。ご存知であれば教えて下さいませ。]]></description>
			<content:encoded><![CDATA[<p>app-engine-patchを使っていて、settings.pyに記述されているAUTH_USER_MODELクラスを動的にロードしたかったんですが、簡単に方法が解らなかったのでメモしておきます。要はクラス名が文字列で与えられている場合に、そのクラスにアクセスしたいという話です。</p>
<p><span id="more-1478"></span></p>
<p>まず対象のクラスが既にimportされている状態であれば、組込み関数のglobalsを使えます。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Hoge:
  <span style="color: #ff7700;font-weight:bold;">pass</span>
hoge_klass    = <span style="color: #008000;">globals</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'Hoge'</span><span style="color: black;">&#93;</span>
hoge_instance = hoge_klass<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>しかし設定ファイルに書かれているクラスをロードするケースでは、対象クラスがimportされていない事も多いと思います。そこでクラスを動的にimportしたい訳ですが、僕が調べた限りでは、一旦クラスが属しているモジュールをimportし、そのモジュールからクラスを得るという手順が必要なようです。モジュールからクラスの取得にはgetattrを使います。コードとしては以下になります。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">path_to_class = <span style="color: #483d8b;">'package.module.class_name'</span>  <span style="color: #808080; font-style: italic;"># このクラスをロードしたい</span>
target = path_to_class.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#40;</span>package, module, cls_name<span style="color: black;">&#41;</span>  = <span style="color: black;">&#40;</span>target<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">'.'</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>target<span style="color: black;">&#91;</span>:-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>, target<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># __import__したモジュールからcls_nameクラスを取得</span>
klass = <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span><span style="color: #008000;">__import__</span><span style="color: black;">&#40;</span>module, fromlist=<span style="color: black;">&#91;</span>package<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>, cls_name<span style="color: black;">&#41;</span>  
klass_instance = klass<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>クラスへの絶対パスからpackage名, module名, class名に分解して, __import__, getattrで使用しています。ここで注意したいのは__import__のfromlistにパッケージを指定する必要がある事です。fromlistが指定されないと、例えばpackage.moduleを指定しても期待したmoduleではなく、packageモジュールが返却されます。リファレンスに書かれているのですが、読み落としてしまいハマりました。</p>
<p>ということで一応上記の方法でパスが与えられたクラスをロードできますが、モジュールを介しているのが気持ち悪いです。やりたい事は from package.module import class_name なので、__import__とかで一発で出来そうですが、探せませんでした。ご存知であれば教えて下さいませ。</p>
]]></content:encoded>
			<wfw:commentRss>http://taichino.com/programming/1478/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

