How to call a python file, that needs to import packages? - python

I'm following a tutorial to call python code from a C++ program from the python docs.
Everything works just fine when trying to call the multiply example. Now if I add a line to the python source code importing a library, lets say openpyxl,
from openpyxl import load_workbook
I receive an error from python
ImportError: No module named openpyxl
I thought if I import a system library, I wouldn't have any problems, but I also get an error if I try to import datetime.
I don't have any error if I import the file from the python console. The openpyxl library is installed in my system.
So my question is: how to import python source code that needs to import packages?
EDIT: Ok, I forgot to mention something, I have not been completely honest with you guys, I'm sorry.
Trying to run the example I run into a problem: I couldn't make python found my multiply.py file, and the line PyImport_Import always return null.
My solution was to add the path in which I knew my python source was by using PySys_SetPath. The problem is that I just realized that this function doesn't append a new directory, it just overwrites the PYTHONPATH. So now python can find multiply.py, but absolutly anything else.
Of course I've deleted that line but now I have another question, why does python can't find my source if the file is just in the same directory of the C++ compiled program?
The I realized that my sys.path from my python console was a little different from the path showed in my embedded python: the first one had at the beginning of the list an empty string ''. I'm not a python expert, but when I add that line to my path I could import the multiply.py so it seems that was the reason I couldn't import modules that were located to relative to my executable was the missing of this empty path -but still don't know what it means-.
I have to thank to #paul-evans who give me the idea of adding the path to find my files.

This is what PYTHONPATH is for. You can set it as an environment variable containing a list module directories, or in the code itself something like:
import sys
sys.path.append("path/to/openpyxl/module")

Related

Is it possible to specify the search path for a module in a python script? If it is, how do I do that?

I have been coding in python for about 2 months, but I'm only familiar with basic object-oriented programming, so I do not really understand things like how searching for modules is implemented. (Basically I'm a noob.)
I pip installed a package called Opentrons Opentrons 2.5.2 and all its dependencies into the samefolder as a python script I'm currently writing. However when I tried to import the module below[1], I get an error saying that "Opentrons is not a module". Then, I tried shifting it into the python library because I found out the search path using the pprint module and it seems to work. I was wondering if I can specify the search path from the .py file itself instead of manually printing the search path and putting the file into the library that the script searches for. (Willing to put in images of the directories I put the opentrons package in if it helps.)
[1]
import sys
import pprint
pprint.pprint(search.path)
from opentrons import robot, containers, instruments
Edit: I realise that the fact that I am running all my scripts in a Spyder console located in a python 3.6 environment might be important.
You can try using the __import__ function, or importlib. This should allow you to specify the path.

Problems importing a python module in Maya and it being recognized

Still learning certain things about Python... I am having issues recognizing my Python script in my scripts dir. First, I checked to see that my path is set correctly:
import sys
for pythonPath in sys.path:
print pythonPath
And C:/Users/..../Documents/maya/2014-x64/scripts is listed, which is where I am placing swap.py
In Maya's script editor I am typing the following:
import swap
reload(swap)
swap.printSomething()
I get:
Error: AttributeError: file line 3: 'module' object has no attribute 'printSomething' #
If I take the same code and throw it into a package...
C:/Users/..../Documents/maya/2014-x64/scripts/swapPackage/swap.py
And then call this, it works...
import swapPackage.swap as swap
reload(swap)
swap.printSomething()
Why? I am totally confused. Mel scripts even run fine from this location as well. I just can't get a simple python script to import and run.
Also something I noticed. Even though I can get this script to run in a package, the package name must be totally different than the module name. I can't have a package named this:
C:/Users/..../Documents/maya/2014-x64/scripts/swap/swap.py
but I can have one where the package name is different:
C:/Users/..../Documents/maya/2014-x64/scripts/swapPackage/swap.py
Ok folks, I was able to solve this by executing a print of my file, only to find out that it was sourcing a totally different version someone copied elsewhere. ARGH. This solves both issues, and makes sense why changing the package name from the module worked.
import swap
reload(swap)
print swap.__file__

Including xlrd/xlwt/xlutils with modules outside of python installation

I'm self-taught in the Python world, so some of the structural conventions are still a little hazy to me. However, I've been getting very close to what I want to accomplish, but just ran into a larger problem.
Basically, I have a directory structure like this, which will sit outside of the normal python installation (this is to be distributed to people who should not have to know what a python installation is, but will have the one that comes standard with ArcGIS):
top_directory/
ArcToolbox.tbx
scripts/
ArcGIStool.py (script for the tool in the .tbx)
pythonmod/
__init__.py
general.py
xlrd/ (copied from my own python installation)
xlwt/ (copied from my own python installation)
xlutils/ (copied from my own python installation)
So, I like this directory structure, because all of the ArcGIStool.py scripts call functions within the pythonmod package (like those within general.py), and all of the general.py functions can call xlrd and xlwt functions with simple "import xlrd" statements. This means that if the user desired, he/she could just move the pythonmod folder to the python site-packages folder, and everything would run fine, even if xlrd/xlwt/xlutils are already installed.
THE PROBLEM:
Everything is great, until I try to use xlutils in general.py. Specifically, I need to "from xlutils.copy import copy". However, this sets off a cascade of import errors. One is that xlutils/copy.py uses "from xlutils.filter import process,XLRDReader,XLWTWriter". I solved this by modifying xlutils/copy.py like this:
try:
from xlutils.filter import process,XLRDReader,XLWTWriter
except ImportError:
from filter import process,XLRDReader,XLWTWriter
I thought this would work fine for other situations, but there are modules in the xlutils package that need to import xlrd. I tried following this advice, but when I use
try:
import xlrd
except ImportError:
import os, sys, imp
path = os.path.dirname(os.path.dirname(sys.argv[0]))
xlrd = imp.load_source("pythonmod.xlrd",os.path.join(path,"xlrd","__init__.py"))
I get a new import error: In xlrd/init.py, the info module is called (from xlrd/info.py), BUT when I use the above code, I get an error saying that the name "info" is not defined.
This leads me to believe that I don't really know what is going on, because I thought that when the init.py file was imported it would run just like normal and look within its containing folder for info.py. This does not seem to be the case, unfortunately.
Thanks for your interest, and any help would be greatly appreciated.
p.s. I don't want to have to modify the path variables, as I have no idea who will be using this toolset, and permissions are likely to be an issue, etc.
I realized I was using imp.load_source incorrectly. The correct syntax for what I wanted to do should have been:
imp.load_source("xlrd",os.path.join(path,"xlrd","__init__.py"))
In the end though, I ended up rewriting my code to not need xlutils at all, because I continued to have import errors that were causing many more problems than were worth dealing with.

Importing modules from relative path to absolute

I am trying to run a program which it specification say for python 2.6 I am running it with python 2.6.6, so it should work but I found that the importation fails see this question, and this sample:
from rnaspace.dao.storage_configuration_reader import storage_configuration_reader
This is due to a version change (I doubt) or of some of the environment on the original server? A solution is in the question cited, but I there is another way to solve this problem that it doesn't involve to change each file with this kind of importation?
Your import statement assumes python knows where the 'rnaspace' package is. Maybe you need to add the path to the package rnaspace in your include path?
import sys
pathToRnaspace = "/path/to/the/rnaspace/package"
sys.path.append(pathToRnaspace)
from rnaspace.core.putative_rna import putative_rna

Python "Module Not Found" - PYTHONPATH fixes not working

I am working in:
Eclipse
Windows 7
64-bit Python 3.3
I want to import writer.pyx (yes, Cython) into main.py. At the top of main.py, I have the appropriate import statement:
import writer
Both main.py and writer.pyx are in the same directory, and that directory is also in Windows' PYTHONPATH environment variable. However, it gives me the error ImportError: No module named 'writer'. So, as far as I can tell, it should be working.
But, here's the kicker: in that same directory, there's a file called reader.pyx that I'm also importing in main.py - and it works perfectly. No issues, no errors.
So, clear summary:
main.py is importing writer.pyx and reader.pyx
All three files are in the same directory (and PYTHONPATH lists that directory)
reader.pyx imports fine, but writer.pyx throws an ImportError: No module named 'writer'
Any ideas as to how I can fix this?
Visual representation:
import reader
import writer
def function():
# code
P.S. This is not my code, and it used to run just fine on this very computer, and the code has not been changed since. This leads me to believe it's an environment problem, but I'm not sure what. Something with Cython, perhaps? I don't have any real experience with it.
From what I understand, pyx files need to be compiled before they can be loaded. You can do this from within your script by using pyximport, if you first issue:
import pyximport; pyximport.install(pyimport = True)
On top of that, based on the fact that there seems to be another reader.py in your path, I'd suggest you create a folder in the same directory where main.py resides (say you name it test_imports) and put both reader.pyx and writer.pyx there, so that you're sure you're importing those files when you issue:
from test_imports import reader, writer
Note that the test_imports directory will also need an empty __init__.py file that tells Python it is a package.
Are you working in a package? If so you will need to import it using the package name:
from mypackage import writer
There are two option I see.
First, remember that your PYTHONPATH may be different in you eclipse and in your windows. Eclipses changes the path.
Second, please try this
from writer import *
and let us know if the writer package will be found

Categories