Mass importing of a template based system.. Trouble with name substitutions

R

rh0dium

Hi all,

Basically I have a bunch of pluggins in a directory (METDIR). For each
one of these templated pluggins I want to do a specific routine. Let's
start with a basic template

file example1.py
----------------
class example1:
def __init__(self):
print "Initialize"
def run(self):
print "Hi from example 1"
----------------

file example2.py
----------------
class example2:
def __init__(self):
print "Initalize"
def run(self):
print "example 2"
----------------

Now I want to go through each pluggin ( example1.py and example2.py )
and execute run. So here is my code but it doesn't work..


if os.path.isdir(METDIR):
modules = []

# Add the metrics dir toyour path..
sys.path.insert( 0, os.getcwd() + "/" + METDIR )

for metric in glob.glob(METDIR+"/*.py"):
# Now lets start working on the individual metrics
module_name, ext = os.path.splitext(os.path.basename(metric))
try:
module = __import__(module_name)
modules.append( module )
except ImportError , e:
print "Failed import of %s - %s" % ( module_name, e)
pass

for mod in modules:
a = mod.mod()
a.run()

But it doesn't work with the following..

Traceback (most recent call last):
File "./metriX.py", line 109, in main
a = mod.mod()
AttributeError: 'module' object has no attribute 'mod'

So it looks like it's not doing the substitution. Does anyone know how
I can do this?

Thanks much
 
R

Robert Kern

rh0dium said:
Hi all,

Basically I have a bunch of pluggins in a directory (METDIR). For each
one of these templated pluggins I want to do a specific routine. Let's
start with a basic template

file example1.py
----------------
class example1:
def __init__(self):
print "Initialize"
def run(self):
print "Hi from example 1"
----------------

file example2.py
----------------
class example2:
def __init__(self):
print "Initalize"
def run(self):
print "example 2"
----------------

Now I want to go through each pluggin ( example1.py and example2.py )
and execute run. So here is my code but it doesn't work..


if os.path.isdir(METDIR):
modules = []

# Add the metrics dir toyour path..
sys.path.insert( 0, os.getcwd() + "/" + METDIR )

for metric in glob.glob(METDIR+"/*.py"):
# Now lets start working on the individual metrics
module_name, ext = os.path.splitext(os.path.basename(metric))
try:
module = __import__(module_name)
modules.append( module )
except ImportError , e:
print "Failed import of %s - %s" % ( module_name, e)
pass

for mod in modules:
a = mod.mod()
a.run()

But it doesn't work with the following..

Traceback (most recent call last):
File "./metriX.py", line 109, in main
a = mod.mod()
AttributeError: 'module' object has no attribute 'mod'

So it looks like it's not doing the substitution.

Doing what substitution? Neither of the modules that you showed define a
mod() callable and nothing else seems to add one.

--
Robert Kern
(e-mail address removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
 
R

rh0dium

Hi again,

No you're right there isn't a mod.mod I want this to be evaluated from
this

for mod in modules:
a = mod.mod()
a.run()

to this.

for mod in modules:
a = example1.example1()
a.run()

then

for mod in modules:
a = example2.example2()
a.run()

etc.

So how is the substitution not working??


Robert said:
rh0dium said:
Hi all,

Basically I have a bunch of pluggins in a directory (METDIR). For each
one of these templated pluggins I want to do a specific routine. Let's
start with a basic template

file example1.py
----------------
class example1:
def __init__(self):
print "Initialize"
def run(self):
print "Hi from example 1"
----------------

file example2.py
----------------
class example2:
def __init__(self):
print "Initalize"
def run(self):
print "example 2"
----------------

Now I want to go through each pluggin ( example1.py and example2.py )
and execute run. So here is my code but it doesn't work..


if os.path.isdir(METDIR):
modules = []

# Add the metrics dir toyour path..
sys.path.insert( 0, os.getcwd() + "/" + METDIR )

for metric in glob.glob(METDIR+"/*.py"):
# Now lets start working on the individual metrics
module_name, ext = os.path.splitext(os.path.basename(metric))
try:
module = __import__(module_name)
modules.append( module )
except ImportError , e:
print "Failed import of %s - %s" % ( module_name, e)
pass

for mod in modules:
a = mod.mod()
a.run()

But it doesn't work with the following..

Traceback (most recent call last):
File "./metriX.py", line 109, in main
a = mod.mod()
AttributeError: 'module' object has no attribute 'mod'

So it looks like it's not doing the substitution.

Doing what substitution? Neither of the modules that you showed define a
mod() callable and nothing else seems to add one.

--
Robert Kern
(e-mail address removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
 
P

Peter Otten

rh0dium said:
for mod in modules:
a = mod.mod()
a.run()

Puzzle: If mod.mod did what you expect, what would a.run have to do to
maintain consistency?

There would be no way to determine the name of the module bound to the mod
variable, but fortunately the Python developers foresaw your problem and
stashed it (the name) in the __name__ attribute.
Use getattr(obj, attrname) to look up an attribute whose name is not known
at compile time:

for mod in modules:
a = getattr(mod, mod.__name__)()
a.run()

Peter
 
R

rh0dium

Peter said:
Puzzle: If mod.mod did what you expect, what would a.run have to do to
maintain consistency?

I thought that once a = example.example the class is then loaded.
Since my framework defines a python file with a class named the same
within it. So

example1.py contains a class example1 and a module run
example2.py contains a class example2 and a module run
example3.py contains a class example3 and a module run

Additional methods that must be present within the class include a run
method. Since this was by definition I knew I needed to do a
substitution - namely mod.mod ( which was intended to be translated to
example1.example1 ).

What you provided was very slick indeed. I no longer am dependant upon
the naming to get the job done.

Very nice - How does this work if some fool calls one class the same as
the other. I'm assuming the last class will be loaded - not the first.

There would be no way to determine the name of the module bound to the mod
variable, but fortunately the Python developers foresaw your problem and
stashed it (the name) in the __name__ attribute.
Use getattr(obj, attrname) to look up an attribute whose name is not known
at compile time:

OUTSTANDING!! Thanks so much!
 
D

Dennis Lee Bieber

So how is the substitution not working??
What substitution?

"mod", as used in the loop, is just a name that is attached to a
module object... It is /not/ "example1", "example2", etc.

mod.mod()

The first mod is the name used inside the loop, and is associated with
the code of the current module. The .mod is an attribute that is
expected to be found inside the module object, and bears no relationship
to the mod used in the loop statement.

I'm having trouble coming up with a good simile... but...

Imagine your modules are envelopes in an inbox (on a desk).

for mod in modules: #modules is the inbox

is taking a post-it sticky note with "mod" written on it, and putting it
on the outside of an envelope.

a = mod.mod()

says, "take the envelope with 'mod' stuck to it, open it up, and look
for a sheet of paper with a SECOND sticky note 'mod' stuck to it, and
read the sheet of paper". When done, the "for" loop moves the outside
sticky note to the next envelope.

Your error message is telling you that none of the envelopes has
a sticky note "mod" INSIDE.

Try a dictionary instead of a list and see if the following
changes do anything for you.

modules = {}
modules[module_name] = module

for (name, mod) in modules.items():

a = getattr(mod, name)

--
 
D

Dennis Lee Bieber

Additional methods that must be present within the class include a run
method. Since this was by definition I knew I needed to do a
substitution - namely mod.mod ( which was intended to be translated to
example1.example1 ).

But Python does NOT do "substitution"... Variables (like "mod")
are just names attached to things, and have no bearing on any other
names that might be attached to the thing.
Very nice - How does this work if some fool calls one class the same as
the other. I'm assuming the last class will be loaded - not the first.

Uh... try it in the interactive prompt and see what happens?

-=-=-=- file x.py
def something():
print "I'm the something in X"

-=-=-=- file y.py
def something():
print "I'm the something in Y"

-=-=-=-= file main.py
import x
import y

y.something()
x.something()

z = y
z.something()

print id(x), id(y), id(z)

z.something = x.something
z.something()
y.something()

-=-=-=-=-=
I'm the something in Y
I'm the something in X
I'm the something in Y
16028080 16028528 16028528
I'm the something in X
I'm the something in X


--
 

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,754
Messages
2,569,527
Members
44,998
Latest member
MarissaEub

Latest Threads

Top