namespaces and eval

D

dave.g1234

Suppose I have a function in module X that calls eval e.g,

X.py
_______
Def foo(bar):
Eval(bar)
_______

Now eval will be called using the default eval(bar,globals(),locals())
and globals will pull in anything in module X.

Now I have module Y that calls bar like so
Y.py
________
from x import *
def biz():
print "Im a silly example!"
Foo("biz()")
_______

Python will complain that it cannot find biz because it's not the X
module.

My question - is there any way to a) get a listing of active namespaes
search ALL active namespaces for a particular variable b) get the
namespace of the caller withing passing it in (here, Y) c) do anything
else to get biz without passing foo("biz()",locals(),globals()) or
hacking biz into the __builtin__ namespace(don't know if it's even
possible, but it defeats the purpose of what I'm trying to do) ? I
realize this is here for a reason, but I'm working on something that's
kind of a hack already

Thanks
dave


More gratuitous context. Long story I'm trying to write a hack for a
concise way of adding arbitrary methods to objects for JPA/JQuery like
chaning eg.

def foo(self):


class wrap:
def __init__(self, obj, globalz=globals(),localz= locals()):
self.obj = obj
self.localz = localz;
self.globalz = globalz;

def __callback__(self, *args, **kw):
newargs = [self.obj];
newargs.extend(args);
print locals
ret = eval(self.name, self.globalz, self.localz)
(*newargs,**kw);
return wrap(ret);

def __getattr__(self,name):
if hasattr(self.obj,name):
return getattr(self.obj,name);
self.name = name;
return self.__callback__;
 
B

bruno.desthuilliers

Suppose I have a function in module X that calls eval e.g,

X.py
_______
Def foo(bar):
Eval(bar)
_______

Now eval will be called using the default eval(bar,globals(),locals())
and globals will pull in anything in module X.

Now I have module Y that calls bar like so
Y.py
________
from x import *
def biz():
print "Im a silly example!"
Foo("biz()")
_______

Python will complain that it cannot find biz because it's not the X
module.

I'm afraid you're using the wrong tool here. Just try this:

# module x
def foo(bar):
bar()

# module y
from x import foo
def baaz():
print "in y.baaz"

foo(baaz)

Remember that in Python, everything (at least, everything you can bind
to a nme) is an object, including functions, classes and modules. And
that every name lives in a namespace, that can be inspected somehow
(using globals() and locals(), but also using getattr() or some
function from the inspect module). IOW, when you think that eval() (or
exec()) is what you need, odds are there's a way better solution.
FWIW, I must have used exec twice and eval thrice in 7+ years of
Python programming - and believe me, I'm not afraid of wizardry and
black magic.
 
D

dave.g1234

Thanks for the responses. I'm well aware that the function can be
passed in the parameters, passing in the functino as an arg defeats
the purpose of what I'm going after.

@ Arnaud - Nice. I'm not sure what the performance of mine vs. yours,
but a perfunctory glance looks like we're doing the close to the same
thing. Maybe one advanage to doing it wrap(x).foo().... is that you
can pass in other parameters to foo. Of course, getting the callers
locals/globals is bad in of itself.

best,
dave
 
B

bruno.desthuilliers

Thanks for the responses. I'm well aware that the function can be
passed in the parameters, passing in the functino as an arg defeats
the purpose of what I'm going after.

Why so ?
@ Arnaud - Nice. I'm not sure what the performance of mine vs. yours,
but a perfunctory glance looks like we're doing the close to the same
thing. Maybe one advanage to doing it wrap(x).foo().... is that you
can pass in other parameters to foo.

I may be wrong (if so please pardon my lack of intelligence and/or
provide a couple use case), but it looks like you're trying to
reinvent partial application.

from functools import partial
def foo(x, y):
return x + y

pfoo = partial(foo, 2)
print pfoo(42)

Don't know if this helps...
 
D

dave.g1234

Why so ?

I may be wrong (if so please pardon my lack of intelligence and/or
provide a couple use case), but it looks like you're trying to
reinvent partial application.

from functools import partial
def foo(x, y):
return x + y

pfoo = partial(foo, 2)
print pfoo(42)

Don't know if this helps...

Ok, so that solves the issue of the aforementioned compose function.
We could do compose( partialfoo,....) ) etc (although I might say I
prefer wrap(x).foo(23).foo(16 ..etc ) The original idea was to
provide wrapper around an object that lets you call abritrary
functions on that object with it as a parameter - i.e., as if it were
a method in a class. The partial function was only a component of the
code I posted earlier. Or am I missing something you're saying?

best
dave
 
A

Arnaud Delobelle

Ok, so that solves the issue of the aforementioned compose function.
We could do compose( partialfoo,....) ) etc (although I might say I
prefer wrap(x).foo(23).foo(16 ..etc ) The original idea was to
provide wrapper around an object that lets you call abritrary
functions on that object with it as a parameter - i.e., as if it were
a method in a class. The partial function was only a component of the
code I posted earlier. Or am I missing something you're saying?

Ok so you want to do

wrap(x).foo(42).bar('spam')...

What is the advantage over

foo(x, 42)
bar(x, 'spam')
...

?
 
D

dave

Ok so you want to do

wrap(x).foo(42).bar('spam')...

What is the advantage over

foo(x, 42)
bar(x, 'spam')
...

?



*shrug*, just syntactic preference I guess. In jquery, for example,
you are working over sets of DOM elements and it's convenient to chain
those statements into a single line of x.foo().bar().biz() etc. IMO
it's a little cleaner to do that as an 'atomic' line, but it's not
really that different. Ideally the classes you are using would
support this without 'wrap' but I was just tinkering with a hack to do
it that way.

Thanks for the help

dave
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,059
Latest member
cryptoseoagencies

Latest Threads

Top