Importing a module dynamically using imp - python

I am trying to import a module from a different directory dynamically. I am following an answer from this question. I have a module named bar in a directory named foo. The main script will be running in the parent directory to foo.
Here is the code i have thus far in my test script (which is running in the parent directory to foo)
#test.py
import imp
mod = imp.load_source("bar","./foo")
and code for bar.py
#bar.py
class bar:
def __init__(self):
print "HELLO WORLD"
But when i run test.py I get this error:
Traceback (most recent call last):
File "C:\Documents and Settings\user\Desktop\RBR\test.py", line 3, in <module>
mod = imp.load_source("bar","./foo")
IOError: [Errno 13] Permission denied

imp.load_source requires the pathname + file name of the module to import, you should change your source for the one below:
mod = imp.load_source("bar","./foo/bar.py")

Appears to be a simple pathing problem - check __file__ or cwd... Maybe try an absolute file path first? - This imp example may help.

Related

Run module (both as a module and) locally as script with local import

I am pretty new to python, so I might be missing (and probably am) some critical part of the import system, but I can't for the life of me figure it out at this point. I have a directory structure as follows:
/
/always_run.py
/lib/__init__.py
/lib/data.py
/lib/config.py
File Internals (imports):
/always_run.py
from lib import data
/lib/data.py
from lib import config
yields
Traceback (most recent call last):
File ".\data.py", line 9, in <module>
from lib import config as configs
ModuleNotFoundError: No module named 'lib'
Note: I've also tried:
from . import config
yields:
Traceback (most recent call last):
File ".\data.py", line 9, in <module>
from . import config as configs
ImportError: cannot import name 'config'
Within data.py I also have:
if __name__ == "__main__":
print("loading myself")
Just to test, but it makes no difference, it never gets to that point
Normally I run my program as python always_run.py and the world is my oyster, but if I try to run data.py directly I always get import failures. (after first cding into the lib directory and running python .\data.py
Is what I am trying to do not possible without adding the local directory to the sys.path, like this(test, works):
import sys
local_path = os.path.dirname(os.path.realpath(__file__))
if local_path not in sys.path:
sys.path.append(local_path)
import config
In the process of writing this, I tested one further thing, cding to the parent directory and running python -m lib.data which works flawlessly. Now my question is one of curiosity, because I still can not find the answer otherwise. Is it not possible to run a local file that is part of a module from the local directory? Or must it be done from another directory?

How to get path of the pyd file aka equivalent of __file__

I have a file package.py that i am trying to package into package.pyd. I have the following statement in package.py
CURR = os.path.dirname(os.path.realpath(__file__))
which works fine when I run package.py but when I import package.pyd into another file wrapper.py I get the following error message
Traceback (most recent call last):
File "C:\Projects\Wrapper.py", line 1, in <module>
import package
File "package.py", line 40, in init package (package.c:4411)
NameError: name '__file__' is not defined
How can I get the location of the .pyd file. Also is there a way to check if it is being run as a .pyd or .py.
Thank you!
It seems that __file__ variable not available in module init.
But you can get __file__ after module was loaded:
def get_file():
return __file__
You can check the __file__ variable to know what file was loaded.
Also keep in mind python's search order: pyd (so), py, pyw(for windows), pyc.
More information about it is in this this question
Found two working methods.
Involving inspect module:
import inspect
import sys
import os
if hasattr(sys.modules[__name__], '__file__'):
_file_name = __file__
else:
_file_name = inspect.getfile(inspect.currentframe())
CURR = os.path.dirname(os.path.realpath(_file_name))
import some file from the same level and using its __file__ attribute:
import os
from . import __file__ as _initpy_file
CURR = os.path.dirname(os.path.realpath(_initpy_file))
Actually, it doesn't have to be __init__.py module, you can add and import any [empty] file to make it work.
__file__ now works in recent more versions of Cython (0.27 ish) when on run on a version of Python that supports multi-phase module initialization (Python >=3.5). See https://github.com/cython/cython/issues/1715 for the point at which it was added.

Python - No module named

I have the following code with few modules:
import Persistence.Image as img
import sys
def main():
print(sys.path)
original_image = img.Image.open_image()
if __name__ == "__main__":
main()
(I've created my own Image module)
And so I'm getting the following error claiming that the Persistence module does not exist:
Traceback (most recent call last):
File "/home/ulises/PycharmProjects/IntelligentPuzzle/Puzzle.py", line 1, in <module>
import Persistence.Image as img
ImportError: No module named Persistence.Image
I've been searching for this problem here but can't find anything that worked to solve this as the directory tree seems to be correct as you can see on this image:
I'm using ubuntu if it's any use.
Thanks and regards!
Persistence package does not exist in that source tree. There is a "Persistence" directory there, but it is not a package, because it does not contain a __init__.py file.
From the Python documentation:
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.
I don't believe that you are importing with proper syntax. You need to use from Persistance import Image as img. For example:
>>> import cmath.sqrt as c_sqrt
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
import cmath.sqrt
ImportError: No module named 'cmath.sqrt'; 'cmath' is not a package
>>> from cmath import sqrt as c_sqrt
>>> c_sqrt(-1)
1j

How to import a function from a module in the same folder? [duplicate]

This question already has answers here:
import function from a file in the same folder
(4 answers)
Closed last month.
I am trying to separate my script into several files with functions, so I moved some functions into separate files and want to import them into one main file. The structure is:
core/
main.py
posts_run.py
posts_run.py has two functions, get_all_posts and retrieve_posts, so I try import get_all_posts with:
from posts_run import get_all_posts
Python 3.5 gives the error:
ImportError: cannot import name 'get_all_posts'
Main.py contains following rows of code:
import vk
from configs import client_id, login, password
session = vk.AuthSession(scope='wall,friends,photos,status,groups,offline,messages', app_id=client_id, user_login=login,
user_password=password)
api = vk.API(session)
Then i need to import api to functions, so I have ability to get API calls to vk.
Full stack trace
Traceback (most recent call last):
File "E:/gited/vkscrap/core/main.py", line 26, in <module>
from posts_run import get_all_posts
File "E:\gited\vkscrap\core\posts_run.py", line 7, in <module>
from main import api, absolute_url, fullname
File "E:\gited\vkscrap\core\main.py", line 26, in <module>
from posts_run import get_all_posts
ImportError: cannot import name 'get_all_posts'
api - is a api = vk.API(session) in main.py.
absolute_url and fullname are also stored in main.py.
I am using PyCharm 2016.1 on Windows 7, Python 3.5 x64 in virtualenv.
How can I import this function?
You need to add __init__.py in your core folder. You getting this error because python does not recognise your folder as python package
After that do
from .posts_run import get_all_posts
# ^ here do relative import
# or
from core.posts_run import get_all_posts
# because your package named 'core' and importing looks in root folder
MyFile.py:
def myfunc():
return 12
start python interpreter:
>>> from MyFile import myFunc
>>> myFunc()
12
Alternatively:
>>> import MyFile
>>> MyFile.myFunc()
12
Does this not work on your machine?
Python doesn't find the module to import because it is executed from another directory.
Open a terminal and cd into the script's folder, then execute python from there.
Run this code in your script to print from where python is being executed from:
import os
print(os.getcwd())
EDIT:
This is a demonstration of what I mean
Put the code above in a test.py file located at C:\folder\test.py
open a terminal and type
python3 C:\folder\test.py
This will output the base directory of python executable
now type
cd C:\folder
python3 test.py
This will output C:\folder\. So if you have other modules in folder importing them should not be a problem
I usually write a bash/batch script to cd into the directory and start my programs. This allows to have zero-impact on host machines
A cheat solution can be found from this question (question is Why use sys.path.append(path) instead of sys.path.insert(1, path)? ). Essentially you do the following
import sys
sys.path.insert(1, directory_path_your_code_is_in)
import file_name_without_dot_py_at_end
This will get round that as you are running it in PyCharm 2016.1, it might be in a different current directory to what you are expecting...

Python script import fails if script is moved to subdirectory

This may be my own misunderstanding of how Python imports and search paths work, or it may be a problem in the packaging of the caldav package.
I have set up a virtualenv environment named myproject
In the top level of myproject, I have a script test.py which contains two imports:
import lxml
import caldav
In this directory, I type:
python test.py
and it works fine without any problem
Now I move the script to the subdirectory test and run the command:
python test/test.py
The import lxml seems to still work. The import caldav fails with the following exception:
Traceback (most recent call last):
File "test/test.py", line 34, in <module>
main()
File "test/test.py", line 29, in main
exec ( "import " + modulename )
File "<string>", line 1, in <module>
File "/home/ec2-user/caldav2sql/myproject/test/caldav/__init__.py", line 3, in <module>
from davclient import DAVClient
File "/home/ec2-user/caldav2sql/myproject/test/caldav/davclient.py", line 8, in <module>
from caldav.lib import error
ImportError: No module named lib
Am I doing something wrong here? Should I be setting up some kind of path?
Most likely, caldav was in the same directory as test.py, so when you import it it worked fine. Now that you moved test.py to a subdirectory, your imports can't find it. You can either move caldav or set your PYTHONPATH.
You could also modify your sys.path
Information from Python's module tutorial: http://docs.python.org/tutorial/modules.html
The variable sys.path is a list of strings that determines the interpreter’s search path for modules. It is initialized to a default path taken from the environment variable PYTHONPATH, or from a built-in default if PYTHONPATH is not set. You can modify it using standard list operations:
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')

Categories

Resources