How can I import a package using __import__() when the package name is only known at runtime?

前端 未结 7 1241
别跟我提以往
别跟我提以往 2020-12-14 21:08

I have a messages folder(package) with __init__.py file and another module messages_en.py inside it. In __init__.py if I import

相关标签:
7条回答
  • 2020-12-14 21:11

    I understand that this question is about the __import__() function but I think the importlib package is best suited for run-time package imports if you are using Python 2.7 or above as advised in the doc:

    Note: Programmatic importing of modules should use import_module() instead of this function.

    Possible Gotcha: This was introduced in python 2.7:

    New in version 2.7.

    This module is a minor subset of what is available in the more full-featured package of the same name from Python 3.1 that provides a complete implementation of import. What is here has been provided to help ease in transitioning from 2.7 to 3.1.

    In your case, you may use:

    import importlib
    
    messages = importlib.import_module('messages_en')
    

    Also, if you wanted to specify the package name, then from messages import messages_en may be written as:

    importlib.import_module('.messages_en', 'messages')

    Note the . in .messages_en used for relative path resolution as described here:

    ... The name argument specifies what module to import in absolute or relative terms (e.g. either pkg.mod or ..mod). If the name is specified in relative terms, then the package argument must be set to the name of the package which is to act as the anchor for resolving the package name (e.g. import_module('..mod', 'pkg.subpkg') will import pkg.mod).

    0 讨论(0)
  • 2020-12-14 21:17

    You need to manually import the top package of your dynamic package path.

    For example in the beginning of the file i write:

    import sites
    

    then later in code this works for me:

    target = 'some.dynamic.path'
    my_module = __import__ ('sites.%s.fabfile' % target, fromlist=["sites.%s" % target])
    
    0 讨论(0)
  • 2020-12-14 21:23

    __import__ is an internal function called by import statement. In everyday coding you don't need (or want) to call __import__

    from python documentation:

    For example, the statement import spam results in bytecode resembling the following code:

    spam = __import__('spam', globals(), locals(), [], -1)
    

    On the other hand, the statement from spam.ham import eggs, sausage as saus results in

    _temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1)
    eggs = _temp.eggs
    saus = _temp.sausage
    

    more info: http://docs.python.org/library/functions.html

    0 讨论(0)
  • 2020-12-14 21:28

    Adding the globals argument is sufficient for me:

    __import__('messages_en', globals=globals())
    

    In fact, only __name__ is needed here:

    __import__('messages_en', globals={"__name__": __name__})
    
    0 讨论(0)
  • 2020-12-14 21:31

    Be sure to append the modules directory to your python path.

    Your path (the list of directories Python goes through to search for modules and files) is stored in the path attribute of the sys module. Since the path is a list you can use the append method to add new directories to the path.

    For instance, to add the directory /home/me/mypy to the path:

    import sys
    sys.path.append("/home/me/mypy") 
    
    0 讨论(0)
  • 2020-12-14 21:31

    You could try this:

    messages == __import__('Foo.messages_en', fromlist=['messages_en'])
    
    0 讨论(0)
提交回复
热议问题