[Tutor] Where am I mistaken? (exec not working as I expect)

Steven D'Aprano steve at pearwood.info
Mon Mar 13 21:21:57 EDT 2017


Hello Francesco, and welcome!

My comments below.

On Sun, Mar 12, 2017 at 11:48:35PM +0100, Francesco Loffredo via Tutor wrote:

> I did only find a way to access the current document, but that's
> all. Armed with that, and hoping to find some field names, I wrote a
> small routine to inspect the types of all elements in that document,
> and I stumbled in a strange behaviour in the exec() function: it seems
> that exec() only works if called from the interactive interpreter,
> while it doesn't if called inside a program.
> Why? 

That is definitely not the case. You must be misinterpreting what you 
are seeing. Unfortunately, your code is so complex I cannot easily see 
where the problem is. Perhaps later I will have time to study it in more 
detail, or somebody else will.

But you do not need exec here at all. exec is a very powerful command, 
but you should treat it as for experts only. Instead of writing:

    exec("qqq = inspect.getmembers(xModel.%s)" % x)

a much safer way is:

    qqq = inspect.getmembers(getattr(xModel, x))

which is faster, easier to understand, and easier to debug.

I also see you have not one, but two bare except clauses:

    try:
        ...
    except:
        ...


This is not a good idea! Please read this:

https://realpython.com/blog/python/the-most-diabolical-python-antipattern/


I think your code is too complex. Here is a simpler function which does 
what you describe as "correct behaviour":

def esplora(xModel):
    i = 0
    for i, name in enumerate(dir(xModel), 1):
        what = type(getattr(xModel, name))
        print(name, what)
    print("Totale elementi: %s" % i)


class prova(object):
    def __init__(self):
        self.abc = "ABC"
        self.num = 123
        self.tup = ("abc", 321)

lui = prova()

esplora(lui)



which gives this result:

__class__ <class 'type'>
__delattr__ <class 'method-wrapper'>
__dict__ <class 'dict'>
__dir__ <class 'builtin_function_or_method'>
__doc__ <class 'NoneType'>
__eq__ <class 'method-wrapper'>
__format__ <class 'builtin_function_or_method'>
__ge__ <class 'method-wrapper'>
__getattribute__ <class 'method-wrapper'>
__gt__ <class 'method-wrapper'>
__hash__ <class 'method-wrapper'>
__init__ <class 'method'>
__le__ <class 'method-wrapper'>
__lt__ <class 'method-wrapper'>
__module__ <class 'str'>
__ne__ <class 'method-wrapper'>
__new__ <class 'builtin_function_or_method'>
__reduce__ <class 'builtin_function_or_method'>
__reduce_ex__ <class 'builtin_function_or_method'>
__repr__ <class 'method-wrapper'>
__setattr__ <class 'method-wrapper'>
__sizeof__ <class 'builtin_function_or_method'>
__str__ <class 'method-wrapper'>
__subclasshook__ <class 'builtin_function_or_method'>
__weakref__ <class 'NoneType'>
abc <class 'str'>
num <class 'int'>
tup <class 'tuple'>
Totale elementi: 28




Hope this helps!



-- 
Steve


More information about the Tutor mailing list