Reload all modules in a directory - python

I need to reload all the python modules within a specified directory.
I've tried something like this:
import sys, os
import_folder = "C:\\myFolder"
sys.path.insert( 0 , import_folder )
for dir in os.listdir(import_folder):
name = os.path.splitext(dir)[0]
ext = os.path.splitext(dir)[1]
if ext == ".py":
import( eval(name) )
reload( eval(name) )
Anyone know how to do this correctly?

import os # we use os.path.join, os.path.basename
import sys # we use sys.path
import glob # we use glob.glob
import importlib # we use importlib.import_module
import_folder = 'C:\\myFolder'
sys.path.append(import_folder) # this tells python to look in `import_folder` for imports
for src_file in glob.glob(os.path.join(import_folder, '*.py')):
name = os.path.basename(src_file)[:-3]
importlib.import_module(name)
reload(sys.modules[name])
importlib.import_module(name)
There is the code. Now to the semantics of the whole thing: using importlib makes this a little bit more normal, but it still promotes some bugs. You can see that this breaks for source files in a subdirectory. What you should probably do is: import the package, (import the whole folder), and use the . operator like so:
import sys # we use sys.path
sys.path.append('C:\\')
import myFolder
...
myFolder.func1(foo)
myFolder.val
bar = myFolder.Class1()
Perhaps you should take a look at the documentation for modules, but don't forget to update the path to include the parent of the folder you want to import.

Related

How to remove PythonCode from the path returned by os.path.dirname(__file__)?

I have a python script in PythonCode folder. I want that I should get the path excluding the PythonCode from it when using os.path.dirname(__file__), currently when I am using os.path.dirname(__file__) it is returning this:-
C:\Users\xyz\Documents\ABC\Python Code
but I need this path:-
C:\Users\xyz\Documents\ABC\
import os
dirname = os.path.dirname(__file__)
print (dirname)
You can wrap dirname once again to go up a directory
dirname=os.path.dirname(os.path.dirname(path))
Just call os.path.dirname() again on what you have:
import os
dirname = r"C:\Users\xyz\Documents\ABC\Python Code"
wanted = os.path.dirname(dirname)
print(wanted) # -> C:\Users\xyz\Documents\ABC
This has been already answered here.
You can do something like this,
import os
print(os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)))
The other answers use os.path, but you could also use the standard library pathlib module (https://docs.python.org/3/library/pathlib.html), which some people prefer because of its more intuitive object-oriented interface:
from pathlib import Path
wanted = Path(__file__).parent.parent
wanted_as_string = str(wanted)

Proper way to dynamically import a module with relative imports?

I need to dynamically import modules into my project from another package.
The structure is like:
project_folder/
project/
__init__.py
__main__.py
plugins/
__init__.py
plugin1/
__init__.py
...
plugin2/
__init__.py
...
I made this function to load a module:
import os
from importlib.util import spec_from_file_location, module_from_spec
def load_module(path, name=""):
""" loads a module by path """
try:
name = name if name != "" else path.split(os.sep)[-1] # take the module name by default
spec = spec_from_file_location(name, os.path.join(path, "__init__.py"))
plugin_module = module_from_spec(spec)
spec.loader.exec_module(plugin_module)
return plugin_module
except Exception as e:
print("failed to load module", path, "-->", e)
It works, unless the module uses relative imports:
failed to load module /path/to/plugins/plugin1 --> Parent module 'plugin1' not loaded, cannot perform relative import
What am I doing wrong?
I managed to solve my own issue after a LOT of googling. Turns out I needed to import using relative paths:
>>> from importlib import import_module
>>> config = import_module("plugins.config")
>>> config
<module 'plugins.config' from '/path/to/plugins/config/__init__.py'>
>>>
I had a similar problem not long ago. I added the path of the project folder to the sys.path using the module's absolute path like this:
import sys
import os
sys.path.append(os.path.dirname(os.path.realpath(__file__))+'/..')
This adds the project_folder to the sys.path thus allowing the import statement to find the plugin modules.

ImportError: No module named modules.TestModule

I have been stuck in this issue for a long time, my project structure goes like this,
import web
import sys
sys.path.append("...")
import modules.TestModule as TM
urls = (
'/testmethod(.*)', 'TestMethod'
)
app = web.application(urls, globals())
class TestMethod(web.storage):
def GET(self, r):
return TM.get_func(web.input().string)
if __name__ == "__main__":
app.run()
When I execute the TestService.py it says "ImportError: No module named modules.TestModule Python"
This is a sample made to test the module.
What is the entry point for your program? Usually the entry point for a program will be at the root of the project. Since it is at the root, all the modules within the root will be importable.
But in your case entry point itself is a level inside the root level.
The best way should be have a loader file (main.py) at root level and rest can be in packages. The other non-recommended way is to append root directory path in sys.path before importing any package.
Add below code before you import your package.
import os, sys
currDir = os.path.dirname(os.path.realpath(__file__))
rootDir = os.path.abspath(os.path.join(currDir, '..'))
if rootDir not in sys.path: # add parent dir to paths
sys.path.append(rootDir)
I have modified yut testscript.py code as below. Please try it out.
import web
import sys
import os, sys
currDir = os.path.dirname(os.path.realpath(__file__))
rootDir = os.path.abspath(os.path.join(currDir, '..'))
if rootDir not in sys.path: # add parent dir to paths
sys.path.append(rootDir)
import modules.TestModule as TM
urls = (
'/testmethod(.*)', 'TestMethod'
)
app = web.application(urls, globals())
class TestMethod(web.storage):
def GET(self, r):
return TM.get_func(web.input().string)
if __name__ == "__main__":
app.run()
If the directory 'DiginQ' is on your python sys.path, I believe your import statement should work fine.
There are many ways to get the directory 'DiginQ' on your python path.
Maybe the easiest (but not the best) is to add a statement like this before you import modules.Testmodule:
import sys
sys.path.extend([r'C:\Python27\DiginQ'])
Based on your post it looks like the path is C:\Python27\DiginQ but if that's not correct just use the right path.
If you google how to set python path you will find many hits. Most important thing is your path has to include the directory above the directory with the package you are attempting to import. In your case, that means DiginQ.

How to change built_in module in python

I want to change os.path in os.py, but it failed. path is different in different platform.
os.py
import ntpath as path
sys.modules['os.path'] = path
from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep, devnull)
It turns out that
from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
devnull)
ImportError: No module named path
Your approach should work. Rename the subdirectory os in your current directory to my_os. Python finds your os directory first and tries to import from there.
Adding this line:
__future__ import absolute_import
to the beginning of the os.py avoids this problem by using absolute imports.
did you try with "__import__" function ?
import mtpath as path
os_path = __import__(path, globals(), locals(), ['curdir', 'pardir', 'sep', 'pathsep', 'defpath', 'extsep', 'altsep', 'devnull']
Then, you can use 'curdir' as :
os_path.curdir
Well, you can also asign it to 'curdir' name as in the documentation :
curdir = os_path.curdir
pardir = os_path.curdir
…

Finding a module's directory

How can I find what directory a module has been imported from, as it needs to load a data file which is in the same directory.
edit:
combining several answers:
module_path = os.path.dirname(imp.find_module(self.__module__)[1])
got me what i wanted
If you want to modules directory by specifying module_name as string i.e. without actually importing the module then use
def get_dir(module_name):
import os,imp
(file, pathname, description) = imp.find_module(module_name)
return os.path.dirname(pathname)
print get_dir('os')
output:
C:\Python26\lib
foo.py
def foo():
print 'foo'
bar.py
import foo
import os
print os.path.dirname(foo.__file__)
foo.foo()
output:
C:\Documents and Settings\xxx\My Documents
foo
This would work:
yourmodule.__file__
and if you want to find the module an object was imported from:
myobject.__module__
The path to the module's file is in module.__file__. You can use that with os.path.dirname to get the directory.
Using the re module as an example:
>>> import re
>>> path = re.__file__
>>> print path
C:\python26\lib\re.pyc
>>> import os.path
>>> print os.path.dirname(os.path.abspath(path))
C:\python26\lib
Note that if the module is in your current working directory ("CWD"), you will get just a relative path e.g. foo.py. I make it a habit of getting the absolute path immediately just in case the CWD gets changed before the module path gets used.

Categories