Is it possible to import a and import b, but have functions from both a and b under a different name?

Example

under a.py there is function jopen()
under b.py there is function ropen()

i want be able to call both of them from c:
c.jopen()
c.ropen()

Recommended Answers

All 7 Replies

in c do from a import *
and from b import *

You must have good reason to do so, however as this from import * is generally bad idea poluting your namespace. It has it's uses, though: I have found it usefull to make alternative itertools module which implements unimplemented function for Python 2.4 and uses builtin one for later versions. Have to give it other name though in order to be able to use itertools from the module. That is not problem to me as generally I use import itertools as it and that can easily be replaced with import it

Why not just do the following?

import a
import b
jopen = a.jopen
ropen = b.ropen

The problem is that functions in a and b can be dynamic and up to n amount of functions, even the filenames can be dynamic.

and they all need to be unified.

The problem is that functions in a and b can be dynamic and up to n amount of functions, even the filenames can be dynamic.

and they all need to be unified.

Then create a specialized class

# python 2
class Unifier(object):
    def __init__(self, *module_names):
        self += module_names
    def __iadd__(self, module_names):
        for name in module_names:
            # if python 3, replace this by builtin function exec.
            exec "from %s import *" % name in self.__dict__
        return self

Then you can write

c = Unifier("a", "b")
# or
c = Unifier()
c += ["a", "b", "os.path"]

Warning: this may fail in the very unlikely case when one of the modules contains a function __iadd__.

commented: Looks wicked! +2

I'm not exactly sure on how this works. Can you please elaborate? Thanks a lot.

My main problem is how the exec statement really work and why is it name in self.__dict__, and how the functions got appended into the Unifier object

I'm not exactly sure on how this works. Can you please elaborate? Thanks a lot.

My main problem is how the exec statement really work and why is it name in self.__dict__, and how the functions got appended into the Unifier object

It's easy to understand. A statement like from socket import * is always executed
in a namespace, and the symbols of module socket are added to this namespace. The namespace can
be any dictionary. When you write this in your program, the namespace is usually the namespace of
the current module, but you can write

D = dict()
exec "from socket import *" in D

and the symbols from the socket module are added to the dictionary D instead of the current namespace.
In the Unifier class, I add the symbols to the Unifier instance's __dict__ dictionary,
so that the symbols can be accessed as the instance's attributes.
Here is a better Unifier class where you can unify with module names or other unifier objects

# python 2
"""module modunifier.py"""

class Unifier(object):
    """Unifier(*items) -> a new unifier object.

    @items: a sequence of (possibly compound) module names or Unifier instances.
    All the modules exportable names become attributes of the unifier object.
    
    """
    def __init__(self, *items):
        self += items
    def __iadd__(self, items):
        for item in items:
            if isinstance(item, Unifier):
                self.__dict__.update(item.__dict__)
            else:
                # if python 3, replace this by builtin function exec.
                exec "from %s import *" % item in self.__dict__
        return self

if __name__ == "__main__":
    u = Unifier("os.path", "socket")
    # symbols from modules os.path and socket can be accessed through u.
    print u.error
    print u.isdir
    
""" my output -->
<class 'socket.error'>
<function isdir at 0x7ffa89a05140>
"""

ahh that makes sense. I thought name in self.__dict__ was executed first, which would then return True or False.

also i wasn't familiar with exec statement. I should look up on that.

Thanks a lot.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.