dynamically adding some of one module's functions to another

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Tue Aug 26 15:42:03 EDT 2008


Gabriel Rossetti a écrit :
> Hello everyone,
> 
> I'm trying to import some modules into another's namespace (network_utils)
> 
> network_utils.py:
> 
> import utils
> import constants as main_const
> from services import constants as srv_const
> from plugins import constants as plg_const
> 
> #
> # Import all the message creation functions
> #
> f = dict([ (f, eval("utils." + f)) for f in dir(utils) if 
> f.startswith("create") ])

As usual, you don't need eval here. Use getattr instead:

create_functions = dict(
    (name, getattr(utils, name)
    for name in dir(utils)
    if name.startswith('create')
    )

> __builtins__.update(f)


Python 2.5.1 (r251:54863, Apr  6 2008, 17:20:35)
[GCC 4.1.2 (Gentoo 4.1.2 p1.0.2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
 >>> __builtins__
<module '__builtin__' (built-in)>
 >>> type(__builtins__)
<type 'module'>
 >>> __builtins__.update
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'update'
 >>>

Anyway, adding to builtins is certainly not the best thing to do. I 
don't know what you're trying to do here, but looks like a very ugly 
mess to me.

> del utils
> 
> #
> # Create a virgin namespace
> #
> class constants:
>    """
>    An aggragation of L{constants},
>    L{services.constants}, &
>    L{plugins.constants}
>    """
>    pass


> #
> # Import all the constants into the new namespace
> #
> f = dict([ (f, eval("main_const." + f)) for f in dir(main_const) if 
> f.isupper() ])
> constants.__dict__.update(f)
> del main_const
> f = dict([ (f, eval("srv_const." + f)) for f in dir(srv_const) if 
> f.isupper() ])
> constants.__dict__.update(f)
> del srv_const
> f = dict([ (f, eval("plg_const." + f)) for f in dir(plg_const) if 
> f.isupper() ])
> constants.__dict__.update(f)
> del plg_const

Yuck.

In your constants.py file, just add the relevant imports:

   from services.constants import *
   from plugins.constants import *

And then in your network_utils file:

   import constants

But this is still a mess to me. The nice point with explicit import and 
modules namespaces is that you at least have a chance to know where a 
given symbol comes from.

> 
> now, if I import network_utils somewhere, and try to call 
> network_utils.myFunction() I get :
> 
>  >>> import network_utils
>  >>> network_utils.myFunction
> Traceback (most recent call last):
>  File "<console>", line 1, in <module>
> AttributeError: 'module' object has no attribute 'myFunction'

And ? Where is the name myFunction bound in the above code ?

> but if I try to access the constants class:
> 
>  >>> from network_utils import constants
>  >>> constants.NO_DATA_TYPE
> 'none'
> 
> it works, how come?

I suppose NO_DATA_TYPE is defined somewhere in one of your constants.py 
files.

Instead of messing with eval and builtins and wonder why something 
"works" and why something else doesn't, I strongly suggest you (re)read 
the part about imports, packages, modules etc in the FineManual.



More information about the Python-list mailing list