<?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>Electric Words &#187; hacks</title>
	<atom:link href="http://www.electricwords.org/tags/hacks/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.electricwords.org</link>
	<description>Dan Ellis's technical blog</description>
	<lastBuildDate>Fri, 27 Nov 2009 08:14:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Injecting attributes into Python modules</title>
		<link>http://www.electricwords.org/2009/11/injecting-attributes-into-python-modules/</link>
		<comments>http://www.electricwords.org/2009/11/injecting-attributes-into-python-modules/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 08:13:49 +0000</pubDate>
		<dc:creator>dan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[hacks]]></category>

		<guid isPermaLink="false">http://www.electricwords.org/?p=55</guid>
		<description><![CDATA[One of the things I don&#8217;t like about Django is the amount of boilerplate imports you end up having at the beginning of modules, especially those modules that are more like configuration files. It spoils the DSL-like nature of them, and I wanted a way to be able to import a module with certain attributes [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things I don&#8217;t like about Django is the amount of boilerplate imports you end up having at the beginning of modules, especially those modules that are more like configuration files. It spoils the DSL-like nature of them, and I wanted a way to be able to import a module with certain attributes already defined. The <code>__import__</code> function doesn&#8217;t allow you to do this, because the <code>locals</code> argument is ignored, so I needed another way. Before I describe the method I came up with, here&#8217;s how you might use it:</p>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> elixir
<span style="color: #ff7700;font-weight:bold;">from</span> inject <span style="color: #ff7700;font-weight:bold;">import</span> module_inject
module_inject<span style="color: black;">&#40;</span><span style="color: #483d8b;">'myapp.models'</span>, elixir<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">import</span> myapp.<span style="color: black;">models</span></pre></div></div>


<p>Easy!</p>

<p><a href="http://www.python.org/dev/peps/pep-0302/">PEP 302</a> describes the import hooks that have been available since Python 2.3, and defines an import protocol. By adding an object with <code>find_module</code> and <code>load_module</code> methods to <code>sys.meta_path</code>, you can get hooked into the import process. <code>find_module</code> is called with the module name to see if an object knows how to load it. <code>load_module</code> is then called to do the actual loading. The class below implements both of those methods.</p>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> InjectionLoader<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</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>, name, dicts<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">name</span> = name
        <span style="color: #008000;">self</span>.<span style="color: black;">dicts</span> = dicts
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> find_module<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, fullname, path=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> fullname == <span style="color: #008000;">self</span>.<span style="color: black;">name</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> load_module<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, fullname<span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># Get the leaf module name and the directory it should be found in</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">'.'</span> <span style="color: #ff7700;font-weight:bold;">in</span> fullname:
            package, leaf = fullname.<span style="color: black;">rsplit</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
            path = <span style="color: #dc143c;">sys</span>.<span style="color: black;">modules</span><span style="color: black;">&#91;</span>package<span style="color: black;">&#93;</span>.__path__   
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            leaf = fullname
            path = <span style="color: #008000;">None</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Open the module file</span>
        <span style="color: #008000;">file</span>, filename, _ = <span style="color: #dc143c;">imp</span>.<span style="color: black;">find_module</span><span style="color: black;">&#40;</span>leaf, path<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Get the existing module or create a new one (for reload to work)</span>
        module = <span style="color: #dc143c;">sys</span>.<span style="color: black;">modules</span>.<span style="color: black;">setdefault</span><span style="color: black;">&#40;</span>fullname, <span style="color: #dc143c;">imp</span>.<span style="color: black;">new_module</span><span style="color: black;">&#40;</span>fullname<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        module.__file__ = filename
        module.__loader__ = <span style="color: #008000;">self</span>  
&nbsp;
        <span style="color: #dc143c;">code</span> = <span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #008000;">file</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, filename, <span style="color: #483d8b;">'exec'</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Populate the module namespace with the injected attributes</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> d <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">dicts</span>:
            module.<span style="color: #0000cd;">__dict__</span>.<span style="color: black;">update</span><span style="color: black;">&#40;</span>d<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Finally execute the module with its injected attributes</span>
        <span style="color: #008000;">eval</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">code</span>, module.<span style="color: #0000cd;">__dict__</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> module</pre></div></div>


<p>It&#8217;s instantiated with the module name it&#8217;s injecting to, and the dicts it is injecting. To make it easier to use, I wrote a helper function, <code>module_inject</code>. It takes a module name, and one or more dicts or modules. Dicts are injected as-is. Modules have their <code>__dict__</code>s injected, but only those attributes listed in the module&#8217;s <code>__all__</code> attribute, or if that isn&#8217;t present then only those that don&#8217;t begin with a double underscore, are used. This is like doing a <code>from module import *</code> at the beginning of the imported module. Here is its implementation:</p>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> module_inject<span style="color: black;">&#40;</span>name, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Set a hook so that when module 'name' is imported, it is executed with
    the attributes in 'args' already in module scope. The arguments can be
    dictionaries or modules (see 'normalize_dict').&quot;&quot;&quot;</span>
    args = <span style="color: #008000;">map</span><span style="color: black;">&#40;</span>normalize_dict, args<span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">meta_path</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>InjectionLoader<span style="color: black;">&#40;</span>name, args<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> normalize_dict<span style="color: black;">&#40;</span>d<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;If the argument is a module, return the module's dictionary filtered
    by the module's __all__ attribute, otherwise return the argument as-is.
    If the module doesn't have an __all__ attribute, use all the attributes
    that don't begin with a double underscore.&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>d, <span style="color: #dc143c;">types</span>.<span style="color: black;">ModuleType</span><span style="color: black;">&#41;</span>:
        keys = <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>
            d,
            <span style="color: #483d8b;">'__all__'</span>,
            <span style="color: #008000;">filter</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> k: <span style="color: #ff7700;font-weight:bold;">not</span> k.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'__'</span><span style="color: black;">&#41;</span>, d.<span style="color: #0000cd;">__dict__</span>.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: black;">&#41;</span>
        d = <span style="color: #008000;">dict</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>key, d.<span style="color: #0000cd;">__dict__</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> keys<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> d</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.electricwords.org/2009/11/injecting-attributes-into-python-modules/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Initializing attributes from __init__ arguments</title>
		<link>http://www.electricwords.org/2009/10/initializing-attributes-from-init-arguments/</link>
		<comments>http://www.electricwords.org/2009/10/initializing-attributes-from-init-arguments/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 19:44:27 +0000</pubDate>
		<dc:creator>dan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[hacks]]></category>

		<guid isPermaLink="false">http://www.electricwords.org/?p=48</guid>
		<description><![CDATA[Every once in a while, I get fed up of having to do lots of self.foo = foo in Python __init__ methods, and wonder if it couldn&#8217;t be done automatically. I came up with the following function to do just that, but I doubt I&#8217;ll ever use it myself, because it goes against the explicit [...]]]></description>
			<content:encoded><![CDATA[<p>Every once in a while, I get fed up of having to do lots of <code>self.foo = foo</code> in Python <code>__init__</code> methods, and wonder if it couldn&#8217;t be done automatically. I came up with the following function to do just that, but I doubt I&#8217;ll ever use it myself, because it goes against the <em>explicit is better than implicit</em> philosophy of 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/env python</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">inspect</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> init_from_args<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    frame = <span style="color: #dc143c;">inspect</span>.<span style="color: black;">stack</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
    <span style="color: #dc143c;">code</span> = frame.<span style="color: black;">f_code</span>
    var_names = <span style="color: #dc143c;">code</span>.<span style="color: black;">co_varnames</span> <span style="color: #808080; font-style: italic;"># __init__'s parameters and locals</span>
    init_locals = frame.<span style="color: black;">f_locals</span> <span style="color: #808080; font-style: italic;"># __init__'s dict of locals</span>
    num_args = <span style="color: #dc143c;">code</span>.<span style="color: black;">co_argcount</span> <span style="color: #808080; font-style: italic;"># Number of arguments</span>
    arg_names = var_names<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>:num_args<span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># Positional argument names</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># If there's a **kwargs parameter, get the name of it</span>
    kw_name = <span style="color: #008000;">None</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">code</span>.<span style="color: black;">co_flags</span> | <span style="color: #ff4500;">12</span>:
        kw_name = var_names<span style="color: black;">&#91;</span>num_args + <span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #dc143c;">code</span>.<span style="color: black;">co_flags</span> | <span style="color: #ff4500;">8</span>:
        kw_name = var_names<span style="color: black;">&#91;</span>num_args<span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Copy the positional arguments</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> name <span style="color: #ff7700;font-weight:bold;">in</span> arg_names:
        <span style="color: #008000;">setattr</span><span style="color: black;">&#40;</span>init_locals<span style="color: black;">&#91;</span>var_names<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>, name, init_locals<span style="color: black;">&#91;</span>name<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># If there was a **kwargs parameter, copy the keywork arguments.</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> kw_name:
        <span style="color: #ff7700;font-weight:bold;">for</span> name, value <span style="color: #ff7700;font-weight:bold;">in</span> init_locals<span style="color: black;">&#91;</span>kw_name<span style="color: black;">&#93;</span>.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            <span style="color: #008000;">setattr</span><span style="color: black;">&#40;</span>init_locals<span style="color: black;">&#91;</span>var_names<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>, name, value<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Foo:
    <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>, a, b, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
        init_from_args<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        bar = <span style="color: #ff4500;">123</span>
        baz = <span style="color: #483d8b;">&quot;hello&quot;</span>
        quux = <span style="color: #483d8b;">&quot;foo&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    foo = Foo<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span>, something=<span style="color: #483d8b;">&quot;something else&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> foo.<span style="color: #0000cd;">__dict__</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.electricwords.org/2009/10/initializing-attributes-from-init-arguments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
