eval function not working how i want it dag namn
Peter Otten
__peter__ at web.de
Fri Apr 15 11:33:20 EDT 2005
robcarlton wrote:
> hi everybody
> I've written this function to make a list of all of an objects
> attributes and methods (not for any reason, I'm just learning)
>
> def list_members(obj)
> l = dir(obj)
> return map(lambda x : eval('obj.'+x), l)
>
> but I get an error saying that obj isn't defined. As I understand it
> eval has access to the current local namespace, which does contain
> object, so I'm not sure whats going wrong.
>
> ps Im sure there are better ways of doing the above which doesn't call
> the eval function, and while I'd be glad to know what it is, I'd still
> like to understand why my way isnt working
It would work if obj were in the local namespace like so:
>>> def f(obj="x"):
... return eval("obj")
...
>>> f()
'x'
but with the lambda you are introducing a nested namespace.
>>> def f(obj="x"):
... return (lambda: eval("obj"))()
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in f
File "<stdin>", line 2, in <lambda>
File "<string>", line 0, in ?
NameError: name 'obj' is not defined
You are doing the equivalent to
>>> def f(obj="x"):
... def g(): # no obj in g()'s namespace
... return eval("obj")
... return g()
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 4, in f
File "<stdin>", line 3, in g
File "<string>", line 0, in ?
NameError: name 'obj' is not defined
only in a convoluted way. Let's make f()'s local variable obj visible in
g(), too:
>>> def f(obj="x"):
... def g():
... obj # now you can see me
... return eval("obj")
... return g()
...
>>> f()
'x'
Here's another way that is viable with lambda, too.
>>> def f(obj="x"):
... return (lambda obj=obj: eval("obj"))()
...
>>> f()
'x'
I'm sure you can fix your list_members() accordingly. Note that rebinding
obj between the definition and call of g() will affect the result only in
the first of the last two examples.
And now for something completely different:
>>> def list_members(obj):
... return [getattr(obj, name) for name in dir(obj)]
...
>>> import os
>>> list_members(os)[:5]
[73, 78, 65, 74, 68]
>>>
Peter
More information about the Python-list
mailing list