Introspection at the module level?

R

Roy Smith

I've got a module that defines a bunch of constants:

OP_FOO = 1
OP_BAR = 2
OP_BAZ = 37

and so on. The values are all unique. I want to build, at module
import time, a reverse map of these constants, i.e. I want to end up
with:

{1: "OP_FOO", 2: "OP_BAR", 37: "OP_BAZ"}

I can find the appropriate symbols:

for name in dir():
if name.startswith ("OP_"):
print name

But I don't see how to get the values. Getattr() is sort of what I
want, but it works on objects, not modules. Not to mention that I don't
see how to get a handle to the module from inside the module, i.e.
there's no "self".

What am I missing?
 
S

Sean Ross

Roy Smith said:
I've got a module that defines a bunch of constants:

OP_FOO = 1
OP_BAR = 2
OP_BAZ = 37

and so on. The values are all unique. I want to build, at module
import time, a reverse map of these constants, i.e. I want to end up
with:

{1: "OP_FOO", 2: "OP_BAR", 37: "OP_BAZ"}

I'm not sure how to do this "at module import time", but if you just
want to build a reverse dictionary of globals variables that start with
"OP_", you can try this:

rd = dict([(v,k) for k,v in globals().copy().iteritems() if
k.startswith("OP_")])

Not to mention that I don't
see how to get a handle to the module from inside the module, i.e.
there's no "self".

http://groups.google.ca/[email protected]&rnum=6
 
P

Peter Hansen

Roy said:
I've got a module that defines a bunch of constants:

OP_FOO = 1
OP_BAR = 2
OP_BAZ = 37

and so on. The values are all unique. I want to build, at module
import time, a reverse map of these constants, i.e. I want to end up
with:

{1: "OP_FOO", 2: "OP_BAR", 37: "OP_BAZ"}

I can find the appropriate symbols:

for name in dir():
if name.startswith ("OP_"):
print name

But I don't see how to get the values. Getattr() is sort of what I
want, but it works on objects, not modules. Not to mention that I don't
see how to get a handle to the module from inside the module, i.e.
there's no "self".

What am I missing?

globals()

That returns a dict which has those constants in it, so you can ask for
..keys() or .values(), etc.

Think of dir() as just globals().keys() in this case...

-Peter
 
T

Terry Reedy

Roy Smith said:
But I don't see how to get the values. Getattr() is sort of what I
want, but it works on objects, not modules.

Yes it does
m = __import__(__name__)
setattr(m, 'a', 3)
dir(m) ['__builtins__', '__doc__', '__name__', 'a', 'm']
getattr(m, 'a')
3

I don't see how to get a handle to the module from inside the module, i.e.
there's no "self".

You have to define it yourself. See above.
What am I missing?
d={} # then, inside your loop:
d[getattr(m,name)] = name #should do what you said you want

Terry J. Reedy
 
S

Sean Ross

Roy Smith said:
Not to mention that I don't
see how to get a handle to the module from inside the module, i.e.
there's no "self".

There are a couple of ways to get hold of the module from inside. My
previous post contained a link to one method. Here's a couple of other
quick ways:

import __main__ as main

or
{'a': 'A', '__builtins__': <module '__builtin__' (built-in)>, ... }
 
S

Skip Montanaro

Roy> I've got a module that defines a bunch of constants:
Roy> OP_FOO = 1
Roy> OP_BAR = 2
Roy> OP_BAZ = 37

Roy> and so on. The values are all unique. I want to build, at module
Roy> import time, a reverse map of these constants, i.e. I want to end
Roy> up with:

Roy> {1: "OP_FOO", 2: "OP_BAR", 37: "OP_BAZ"}

Have a look at

http://manatee.mojam.com/~skip/python/ConstantMap.py

Skip
 
R

Roy Smith

Skip Montanaro said:

This pointed me to the simpliest solution. I ended up with:

map = {}
for name, value in globals().items():
if name.startswith ("OP_"):
map[value] = name

which seems to work just fine. Thanks to everybody who responded with
suggestions.

The danger here is that I'm depending on the fact that there are no
globals defined elsewhere in the system which start with "OP_", but that
seems like a pretty minimal risk. In fact, it looks like all the
externally defined globals are of the form __xxx__.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top