Python Searching for files and Importing them - python

I need to write a function that walks through directories searching for files that end in _prj.py, and then extract some lists from there. The way I'm doing it right now is by using os.path.walk and then importing. My code looks like this:
for py_file in files:
if py_file.endswith("_prj.py"):
print py_file[:-3]
module = py_file[:-3]
import module
However, I get an import error:
ImportError: No module named module
I think I understand why, I'm just not sure how I would make the import statement work. Is there a way to make the module variable be read as the file name instead of "module"?

The correct way of import a module by a String name is by using another module known as importlib
import importlib
math_module = importlib.import_module("math")
print math_module.sqrt(25)
>>> 5.0

Related

Python file imports using a string

I am trying to import a function from another python file in a different directory but only have the function name in string form. I have tried using import lib as follows:
sys.path.insert(1, file_path) # Works fine
import file # Works fine
run_function = importlib.import_module("file.function"+str(loop)) # Error occurs here
But when I try this I get the error message: ModuleNotFoundError: No module named 'file.function1'; 'file' is not a package
I have also tried doing:
from file import *
eval("function{loop}()")
But with this method I recieve the error message: SyntaxError: import * only allowed at module level
I am not sure exactly how to fix the issue or whether there would be a better way of doing this. I am open to suggestions. Thanks!
You can import anywhere in the file (obviously importing within a function would limit the module scope to the function itself).
def func(x):
for i in range(x):
eval(f"from lib import function{i}")
# All functions available in this scope
For extra safety, I recommend this be put into a try/catch.
You don't import functions. You have successfully imported the module, which includes the function, so all you have to do is get it
sys.path.insert(1, file_path) # Works fine
import file # Works fine
result = getattr(file, "function1")(loop)

How to import an entire module from within the same directory

Sorry if this is a duplicate, but I couldn't find anything for this specific topic. So here's the question:
In python 3 when you want to import an object from some module you would write something like
from module import object
If you want to specify that the module is in the same diretory as the file you're currently working on, you'd precede the module name with a dot like
from .module import object
What do I have to write in order to import an entire module from within the same directory? Intuitively, I tried
import .module
But this gives me a syntax error.
The correct way is to import the module from the current package, i.e. ..
from . import module
This makes the module available with the name module.

Python: NameError when trying to use "re" inside a function

I have a script called main_plotter.py that looks like this:
import re
import numbs
numbs.getSquares("file.csv")
numbs.py is the file that I'm importing from. It looks like this:
def getSquares(sqfile):
infile=sqfile
base_name = re.split(".csv", infile)[0]
print (base_name)
When I run main_plotter.py, I get NameError: name 're' is not defined.
Why is this happening? I tried adding global re before the import re statement, but that doesn't help either. Aren't the import statements supposed to be global anyway? Any help appreciated!
PS. the code runs as expected if I import re inside the numbs.py file.
"Global" in Python means "module namespace". Any import re happens exactly there -- module-by-module; there intentionally does not exist any wider scope, which ensures that the content of any Python module can be understood by reading only that module (unlike Ruby, where to know the context in which code is run you need to read every module that was ever loaded by the same interpreter).
If you want to use the re module in numbs.py, you should have a separate import re inside that file. This doesn't reload the module from disk, but just adds a namespace entry pointing to the already-cached instance that was loaded on first reference.

Toggle between relative and absolute Import of built in module

So I have the script that imports the standard module checkmarc.
import checkdmarc
I want to implement some mock checkmarc that will seat at the same directory as the script.
Now sometime it will be there and I want the script to pull that local module and if it's not there it should take the standard checkmarc.
I know I can do something like if the file in the path exists it'll take that, else do that, but I want to keep the import line just import checkmarc.
From reading: https://docs.python.org/3/whatsnew/2.5.html#pep-328-absolute-and-relative-imports
there's a section of exactly what I need but only for Python 2.4 and lower:
In Python 2.4 and earlier, it will first
look in the package’s directory to perform a relative import, finds
pkg/string.py, imports the contents of that file as the pkg.string
module, and that module is bound to the name string in the pkg.main
module’s namespace.
If there's an elegant way to do it, I'd love to hear.
I don't think you can do this if your custom module has the same name. You can however do something like this:
try:
import customcheckdmarc as checkdmarc
except ImportError:
import checkdmarc as checkdmarc
this will load your customecheckedmarc.py if it's there and will load default checkdmarc otherwise.

python -find which library is currently executed

I need to find out the path for a particular library in my script.
I tried using :
os.path.dirname(MODULE.__file__),
but it gives an attribute error:
"type object 'MODULE' has no attribute '__file__'."
Is there any other way to find the path for a particular module? I do not want to use sys.path as it gives the list of all the libraries.
You have space between underscores _ _ in MODULE.__file__. Call it like:
>>> import os, operator
>>> os.path.dirname(operator.__file__) # where MODULE is "operator"
'/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4'
You can use the both dirname() and basename() if you are going to split the passed filename into components without taking into account the current directory. If you want to also consider the current directory, you have to do so explicitly.
To get the dirname of the absolute path, use
os.path.dirname(os.path.abspath(__file__))
Note: Remove the spaces before file. As the response of #paxdiablo here, when a module is loaded in Python, __file__ is set to its name. You can then use that with other functions to find the directory that the file is located in.
It looks like you are not examining a module, but rather a type object. You might try:
os.path.dirname(MODULE.__module__.__file__)
caveat
Usually you can use the __file__ attribute to find out where the module is located, but as stated in the docs (you have to scroll down a bit or ctrl + f and search for __file__) this attribute is not present.
The __file__ attribute is not present for C modules that are statically linked into the interpreter; for extension modules loaded dynamically from a shared library, it is the pathname of the shared library file.
You can however use the imp module. It has the find_module function which will perform the same search that is performed when you actually import the module. This would lead to code like this:
import imp
data = imp.find_module("MODULE")
# The path of the module is the second element of the tuple
pathname = data[1]
Use os module
os.path.dirname(<module>.__file__)
An example:
>>> import os, requests
>>>
>>> requests.__file__
'/usr/lib/python2.7/site-packages/requests/__init__.pyc'
>>>
>>> os.path.dirname(requests.__file__)
'/usr/lib/python2.7/site-packages/requests'
>>>
>>> os.path.abspath(requests.__file__)
'/usr/lib/python2.7/site-packages/requests/__init__.pyc'
os.path.dirname - just removes the last segment in the path i.e. __init__.pyc - in short it returns the project root.
Actually my code was something like :
from <module> import blah
I was trying to find the module path using :
os.path.dirname(module.__file__)
It gave an error saying "module" does not exist.
So I did :
import module and then
from <module> import blah
Then it worked !!

Categories