How to load all modules in a folder?

后端 未结 18 1633
失恋的感觉
失恋的感觉 2020-11-22 05:37

Could someone provide me with a good way of importing a whole directory of modules?
I have a structure like this:

/Foo
    bar.py
    spam.py
    eggs.py         


        
相关标签:
18条回答
  • 2020-11-22 06:18

    Anurag Uniyal answer with suggested improvements!

    #!/usr/bin/python
    # -*- encoding: utf-8 -*-
    
    import os
    import glob
    
    all_list = list()
    for f in glob.glob(os.path.dirname(__file__)+"/*.py"):
        if os.path.isfile(f) and not os.path.basename(f).startswith('_'):
            all_list.append(os.path.basename(f)[:-3])
    
    __all__ = all_list  
    
    0 讨论(0)
  • 2020-11-22 06:22

    This is the best way i've found so far:

    from os.path import dirname, join, isdir, abspath, basename
    from glob import glob
    pwd = dirname(__file__)
    for x in glob(join(pwd, '*.py')):
        if not x.startswith('__'):
            __import__(basename(x)[:-3], globals(), locals())
    
    0 讨论(0)
  • 2020-11-22 06:23

    I got tired of this problem myself, so I wrote a package called automodinit to fix it. You can get it from http://pypi.python.org/pypi/automodinit/.

    Usage is like this:

    1. Include the automodinit package into your setup.py dependencies.
    2. Replace all __init__.py files like this:
    __all__ = ["I will get rewritten"]
    # Don't modify the line above, or this line!
    import automodinit
    automodinit.automodinit(__name__, __file__, globals())
    del automodinit
    # Anything else you want can go after here, it won't get modified.
    

    That's it! From now on importing a module will set __all__ to a list of .py[co] files in the module and will also import each of those files as though you had typed:

    for x in __all__: import x
    

    Therefore the effect of "from M import *" matches exactly "import M".

    automodinit is happy running from inside ZIP archives and is therefore ZIP safe.

    Niall

    0 讨论(0)
  • 2020-11-22 06:24

    I have also encountered this problem and this was my solution:

    import os
    
    def loadImports(path):
        files = os.listdir(path)
        imps = []
    
        for i in range(len(files)):
            name = files[i].split('.')
            if len(name) > 1:
                if name[1] == 'py' and name[0] != '__init__':
                   name = name[0]
                   imps.append(name)
    
        file = open(path+'__init__.py','w')
    
        toWrite = '__all__ = '+str(imps)
    
        file.write(toWrite)
        file.close()
    

    This function creates a file (in the provided folder) named __init__.py, which contains an __all__ variable that holds every module in the folder.

    For example, I have a folder named Test which contains:

    Foo.py
    Bar.py
    

    So in the script I want the modules to be imported into I will write:

    loadImports('Test/')
    from Test import *
    

    This will import everything from Test and the __init__.py file in Test will now contain:

    __all__ = ['Foo','Bar']
    
    0 讨论(0)
  • 2020-11-22 06:29

    Python, include all files under a directory:

    For newbies who just can't get it to work who need their hands held.

    1. Make a folder /home/el/foo and make a file main.py under /home/el/foo Put this code in there:

      from hellokitty import *
      spam.spamfunc()
      ham.hamfunc()
      
    2. Make a directory /home/el/foo/hellokitty

    3. Make a file __init__.py under /home/el/foo/hellokitty and put this code in there:

      __all__ = ["spam", "ham"]
      
    4. Make two python files: spam.py and ham.py under /home/el/foo/hellokitty

    5. Define a function inside spam.py:

      def spamfunc():
        print("Spammity spam")
      
    6. Define a function inside ham.py:

      def hamfunc():
        print("Upgrade from baloney")
      
    7. Run it:

      el@apollo:/home/el/foo$ python main.py 
      spammity spam
      Upgrade from baloney
      
    0 讨论(0)
  • 2020-11-22 06:29

    See that your __init__.py defines __all__. The modules - packages doc says

    The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all__ variable, described later.

    ...

    The only solution is for the package author to provide an explicit index of the package. The import statement uses the following convention: if a package’s __init__.py code defines a list named __all__, it is taken to be the list of module names that should be imported when from package import * is encountered. It is up to the package author to keep this list up-to-date when a new version of the package is released. Package authors may also decide not to support it, if they don’t see a use for importing * from their package. For example, the file sounds/effects/__init__.py could contain the following code:

    __all__ = ["echo", "surround", "reverse"]

    This would mean that from sound.effects import * would import the three named submodules of the sound package.

    0 讨论(0)
提交回复
热议问题