Note that there are some explanatory texts on larger screens.

plurals
  1. POInjecting "global imports" into Python functions
    text
    copied!<h3>Short, but complete, summary</h3> <p>I want to allow users of my function (a class factory) to inject/overwrite global imports when using my function (longer explanation of rationale below). But there are about 10 different variables that could be passed in and it adds a number of very repetitive lines to the code. (granted, also makes it more complicated to call too :P) Right now, I'm doing something like the following (just simplifying all of this). To make it runnable, I'm using a dummy class, but in the actual script I'd be using <code>import pkg1</code>, etc. Figured this was clearer and shorter than a class factory, etc.</p> <pre><code>class Dummy(object): pass pkg1, pkg2 = Dummy(), Dummy() pkg1.average = lambda *args : sum(args) / len(args) pkg2.get_lengths = lambda *args : map(len, args) def get_average(*args, **kwargs): average = kwargs.get("average") or pkg1.average get_lengths = kwargs.get("get_lengths") or pkg2.get_lengths return average(*get_lengths(*args)) adjusted_length = lambda *args: map(len, args) + [15] print get_average([1,2], [10, 4, 5, 6]) == 3 # True print get_average([1,2], [10, 4, 5, 6], get_lengths=adjusted_length) == 7 # True </code></pre> <h3>Related SO questions</h3> <p>This stack overflow post: <a href="https://stackoverflow.com/questions/1450275/modifying-locals-in-python">Modifying locals in Python</a>, seemed particularly relevant and initially I wanted to just overwrite locals by storing to the locals dictionary but (1) it didn't seem to work, and (2) it seems like it was a bad idea. So, I'm wondering if there's <em>another</em> way to do it.</p> <p>This one looked promising ( <a href="https://stackoverflow.com/questions/2406586/adding-an-object-to-another-modules-globals-in-python">Adding an object to another module&#39;s globals in python</a> ), but I'm not really sure how to access the globals for the current file in the same way as a module. (and this question - <a href="https://stackoverflow.com/questions/11594090/python-mutating-globals-to-dynamically-put-things-in-scope">python: mutating `globals` to dynamically put things in scope</a> - doesn't really apply, since I'm (ultimately) using this to define classes).</p> <p>I guess I could wrap everything in an exec statement (like this post - <a href="https://stackoverflow.com/questions/2904274/globals-and-locals-in-python-exec">globals and locals in python exec()</a> ), but that's both fiddly and means that it's much harder to do error checking/linting/etc.</p> <p>So here's what I'd <em>like</em> to do. (NOTE: I would have used <code>from pkg1 import average</code> AND <code>from pkg2 import get_lengths</code> but I wanted the example to be clearer (need to copy pkg1 and pkg2 above to run this))</p> <pre><code>average = pkg1.average get_lengths = pkg2.get_lengths def get_average(*args, **kwargs): localvars = locals() for k in ("get_lengths", "average"): if kwargs.get(k, None) and kwargs[k] is not None: localvars[k] = kwargs[k] return average(*get_lengths(*args)) print get_average([1,2], [10, 4, 5, 6]) == 3 #True print get_average([1,2], [10, 4, 5, 6], get_lengths=adjusted_length) == 7 # False, is 3 </code></pre> <h3>Rationale for my specific use-case</h3> <p>Right now, I'm trying to write a dynamically-generated class factory (to use as an SQLAlchemy mixin), but I want to allow users of my class to pass in alternate constructors, so they can use SQLAlchemy adapters, etc.</p> <p>For example, Flask-SQLAlchemy provides the same <em>interface</em> as SQLAlchemy, but provides a custom object/class (<code>db</code>) that wraps around all the SQLAlchemy objects to provide more features.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload