Acessing a variable as a string in a module
<p>Following other posts here, I have a function that prints out information about a variable based on its name.  I would like to move it into a module.</p>

<pre><code>#python 2.7
import numpy as np
def oshape(name):
    #output the name, type and shape/length of the input variable(s)
    #for array or list
    x=globals()[name]
    if type(x) is np.array or type(x) is np.ndarray:
        print('{:20} {:25} {}'.format(name, repr(type(x)), x.shape))
    elif type(x) is list:
        print('{:20} {:25} {}'.format(name, repr(type(x)), len(x)))
    else:
        print('{:20} {:25} X'.format(name, type(t)))

a=np.array([1,2,3])
b=[4,5,6]
oshape('a')
oshape('b')
</code></pre>

<p>Output:</p>

<pre><code>a                    &lt;type 'numpy.ndarray'&gt;    (3,)
b                    &lt;type 'list'&gt;             3
</code></pre>

<p>I would like to put this function oshape() into a module so that it can be reused. However, placing in a module does not allow access to the globals from the main module.  I have tried things like 'import __main__ ' and even storing the function globals() and passing it into the submodule.  The problem is that globals() is one function, which specifically returns the globals of the module it is called from, not a different function for each module.</p>

<pre><code>import numpy as np
import olib

a=np.array([1,2,3])
b=[4,5,6]

olib.oshape('a')
olib.oshape('b')
</code></pre>

<p>Gives me:</p>

<pre><code>KeyError: 'a'
</code></pre>

<p>Extra information:
The goal is to reduce redundant typing.  With a slight modification (I took it out to make it simpler for the question), oshape could report on a list of variables, so I could use it like:</p>

<pre><code>oshape('a', 'b', 'other_variables_i_care_about')
</code></pre>

<p>So solutions that require typing the variable names in twice are not really what I am looking for.  Also, just passing in the variable does not allow the name to be printed.  Think about using this in a long log file to show the results of computations &amp; checking variable sizes.</p>

<p>Your logic is way over complicated, you should just pass the arrays themselves as you are also already passing the variable name as a string so you are not looking up something you don't have access to. But if you wanted to make your code work exactly as is you could set an attibute on the module:</p>

<pre><code>import numpy as np
import olib

a = np.array([1, 2, 3])
b = [4, 5, 6]
olib.a = a
olib.b = b
olib.oshape('a')
olib.oshape('b')
</code></pre>

<p>This will take any args and search the module the code is run from for the  attrs:</p>

<pre><code>import numpy as np
import sys
from os.path import basename
import imp

def oshape(*args):
    # output the name, type and shape/length of the input variable(s)
    # for array or list
    file_name = sys.argv[0]
    mod = basename(file_name).split(".")[0]
    if mod  not in sys.modules:
        mod = imp.load_source(mod, file_name)
        for name in args:
            x = getattr(mod, name)
            if type(x) is np.array or type(x) is np.ndarray:
                print('{:20} {:25} {}'.format(name, repr(type(x)), x.shape))
            elif type(x) is list:
                print('{:20} {:25} {}'.format(name, repr(type(x)), len(x)))
            else:
                print('{} {} X'.format(name, type(x)))
</code></pre>

<p>Just pass the variable name strings:</p>

<pre><code>:~/$ cat t2.py 
import numpy as np
from olib import oshape

a = np.array([1, 2, 3])
b = [4, 5, 6]
c = "a str"

oshape("a", "b", "c")


:$ python t2.py 
a                    &lt;type 'numpy.ndarray'&gt;    (3,)
b                    &lt;type 'list'&gt;             3
c &lt;type 'str'&gt; X
</code></pre>

python python-2.7