Python importing modules differently when run interactively/non-interactively - python

One of my Python scripts runs in interactive mode but fails when run from the command line. The difference is that when run from the command line, it imports modules from a bad .egg file, and when run interactively it uses my fixed (unzipped) version in the current directory.
My question is two-fold: a) why does Python load modules differently when run from these locations, and b) what are my options to work around it?

I don't understand what do you mean by running script in interactive mode, so I can't say exactly. But the first place to look for modules (sys.path[0]) in interactive mode is current directory (even calling os.chdir() will affect imports), while for script it's directory where the script is located (derived from sys.argv[0]). Note that they are effectively the same when script is run from directory where it's located, but could be different in other cases. Hope this helps.

On UNIX systems and Mac OS-X:
Do you have a ~/.python-eggs directory?
OS independent:
Are you sure that you use the same Python instance in both cases?
Can you print sys.path in each cases and see which package directory comes first on your module search path?

a) why does Python load modules differently when run from these locations
b) what are my options to work around it?
Check your environment variable PYTHONPATH. When python imports module, it searches those directories. One way to get around your problem is to add your local folder "the (unzipped) version in the current directory" to the beginning of PYTHONPATH so that python will find it first.

This works for me:
import sys
sys.path[0]=''

Related

Executing Python scripts from windows path variable

I have Python 3.7 on my path (I can execute .py scripts when I am in that local directory in cmd)
I also have a folder of scripts on my path (I can open them from any local directory in cmd i.e. by typing "script.py")
However, I cannot execute these scripts from any local directory explicitly using python, i.e. "python script.py"
Any ideas why this is the case? Thanks
Edit:
The desired folder "scripts" is set in PYTHONPATH variable, and checking within python I see
import sys
sys.path
['', 'C:\Users\benma\Desktop\scripts',...
I can import a file from scripts into python already running, but not execute it directly
Python doesn't search PATH to look for your scripts. You can run the script directly because the shell is searching PATH looking for something that matches.
PYTHONPATH won't help when executing from the shell. It is only used by Python when importing modules:
Augment the default search path for module files.
I don't think you're going to get exactly what you're after. The closest is probably executable modules.

What is the purpose of the environmental variable PYTHONPATH

On windows 7, I currently don't have a python path. Can I safely make one? If so, how do I do it?
Upon making this variable, I can no longer load Spyder (IDE) without it crashing. Does anyone know why?
I would like to edit my existing python path if possible, but just don't know why it isn't already there in environmental variables.
I would ultimately like to be able to run "python myscript.py" and have myscript be in a different directory from the call directory.
PYTHONPATH adds new paths to the ones Python uses by default. The path in total determines where Python will look for modules when you import them.
Look at sys.path to see the combination of the defaults with your PYTHONPATH environment variable. It's likely that Spyder is loading a module that exists in two different places and the wrong one comes first.
When you import modules in python, python searches for the module in the directories in PYTHONPATH, in addition to some other directories.
In order to be able to run your script as > myscript.py, you want to put your script somewhere on PATH (here are some instructions for viewing or updating PATH), this is where the OS looks for scripts and programs when you give it a command. I believe that in windows the .py extension must be associated with python for windows to know that myscript.py should be run using python. This should happen automatically when python in installed, but maybe someone with more windows knowledge can comment on this.
it has role similar to path. this variable tells the python interpreter where to
locate the module files imported into a program. it should include the python source library directory and the directories contain in python source code

Python import files mac

I have an exercise for a course in Python I have to complete. I have saved my methods/defs in one file and just need to figure out how to run it. I was hoping you could explain to me how to import files (I know the syntax"import filename"). When ever I do this I get an error. How do I change the file path of the import to the file on my desktop? I am using a mac and running IDLE 2.7.3
If the files are in the same directory as that file you can just use
import <filename> #(without the <>)
However, if you are referring to the files in a separate directory use imp
import imp
module = imp.load_source('module.name', '/path/to/file.py')
module.SomeClass()
On Mac OS X, there are two basic ways to launch IDLE. One is by double-clicking on an IDLE icon from the Applications folder in the Finder. (I'll call that IDLE.app) The second is to launch IDLE from a terminal session shell with something like:
idle2.7
I'll call that bin/idle because it refers to file in one of your system's bin directories.
When launching bin/idle, IDLE will inherit the current working directory of the shell and will add that directory to the front of the list of directories Python searches for imports. You can examine that list of directories in the IDLE shell window:
import sys
sys.path
When you launch IDLE.app, however, it is not associated with any shell so there is no opportunity to tell IDLE which working directory to use. In this case, IDLE.app uses your Documents folder/directory as its working directory: in shell notation, ~/Documents, also spelled /Users/your_login_name/Documents.
You can manually manipulate sys.path in your Python program to add another directory for imports:
import sys
sys.path.insert(0, '/path/to/directory')
Another way to manipulate sys.path is to use the PYTHONPATH environment variable. But, again, when using IDLE.app, there is no (easy) way to pass environment variables to it, unlike with bin/idle
So if you want to use IDLE.app, the simplest approach is to put into your Documents directory all of the files and packages directories that you want to be able to import. Otherwise, use a terminal session, set the desired working directory and/or PYTHONPATH variable and launch bin/idle. So something like:
cd ~/MyProject
export PYTHONPATH=~/"AnotherPackageDirectory"
idle2.7
Yet another approach is to install your modules in the default locations that Python searches and use Distutils or easy_install or pip. But that's something to learn about later when you have a finished project.

How to import modules from alternate locations when using Python IDLE?

I've been trying to figure this out for more than 2 days, screening the internet and the tutorial, but yet I don't have solved my problem. I'm a real newb and don't yet really know what I'm doing..
Software I use:
Mac OS X 10.6
Python v3.2.2
Interactive interpreter (IDLE)
Problem:
IDLE's default directory is /Users/ME/Documents/. Files with the extention .py can only be opened when located in this directory. However, I made a folder where I would like to save all the .py files etc that have to do with this software. Currently, IDLE cannot load .py files from the chosen directory by me.
What I did first was I added to IDLE:
import sys.
sys.path.append('Users/Mydir/')
sys.path
However, in an already existing thread from 2010 I read sys.path is for the Interpreter ONLY, and that if I am to change this I need to modify the PYTHONPATH environment variable:
PYTHONPATH="/Me/Documents/mydir:$PYTHONPATH"
export PYTHONPATH
However, I'm confused how to use this and cannot find answers to my following questions:
1) PYTHONPATH (.py?) is already existing on my computer when I installed the program?
If YES, where is it? I cannot find it anywhere.
If NO, I need to create one. But where and what should be the content so that IDLE can load files from a non-default directory? Should it contain only the words in bold?
I hope I made my problem clear.
Cheers
It's not totally clear to me what you mean by load. That could mean Open and Close files in the IDLE editor. Or it could mean being able to use the Python import statement to load existing Python modules from other files. I'll assume the latter, that by load you mean import.
There are two general ways to launch IDLE on Mac OS X. One is from the command line of a terminal session; if you installed Python 3.2 using the python.org installers, by default typing /usr/local/bin/idle3.2 will work. The other way is by launching IDLE.app from /Applications/Python 3.2, i.e. by double-clicking its icon. Because you say the default directory for files is your Documents folder, I'm assuming you are using the second method because IDLE.app sets Documents as its current working directory, which becomes the default directory for *Open*s and *Save*s and is automatically added as the first directory on Python's sys.path, the list of directories that Python uses to search for modules when importing.
If you want to add other directories to sys.path, as you've noted you can use the PYTHONPATH environment variable to do so. The standard way to do this is to add an export PYTHONPATH=... definition to a shell startup script, like .bash_profile. However, if you use IDLE.app, no shell is involved so commands in .bash_profile have no effect.
While there are ways to modify the environment variables for OS X GUI apps, in this case, a simpler solution is to use the other method to invoke IDLE, from the command line of a shell session, using either /usr/local/bin/idle3.2 or, if you've run the Update Shell Profile command in the /Applications/Python 3.2 folder (and opened a new terminal session), just idle3. Then, a PYTHONPATH environment variable you set up will be inherited by that IDLE.
BTW, there is no direct way to modify the initial current working directory of IDLE.app from Documents other than modifying the code in IDLE. If you start IDLE from a command
line, it inherits the current working directory of the shell.
[UPDATE] But rather than fooling around with defining PYTHONPATH, here is another even simpler, and probably better, approach that should work with either IDLE.app or the command line idle. It takes advantage of Python path configuration (.pth) files and user site-package directories. Assuming you are using a standard Python framework build of 3.2 (like from a python.org installer) on Mac OS X, create a path file for the directory you want to permanently add to sys.path. In a terminal session:
mkdir -p ~/Library/Python/3.2/lib/python/site-packages
cd ~/Library/Python/3.2/lib/python/site-packages
cat >my_paths.pth <<EOF
/Users/YOUR_USER_NAME/path/to/your_additional_python_directory_1
/Users/YOUR_USER_NAME/path/to/your_additional_python_directory_2
EOF
Now, whenever you run that Python 3.2 or IDLE under your user name, the directories you have added to the .pth file will automatically be added to sys.path.
BTW, the exact path location of the user site-packages directory for versions of Python earlier than 3.2 or 2.7 may be slightly different. Also, on other Unix-y systems, the default location for the user site-package directory is ~/.local/lib/python3.2/site-packages.
PYTHONPATH is an environment variable (see here and here). I don't have a Mac, but from the threads I have linked to you would type something like
launchctl setenv PYTHONPATH=/Me/Documents/mydir:$PYTHONPATH
on the command line to allow you to run Python scripts from /Me/Documents/mydir. Alternatively, put this line in a file called .bashrc in your home directory (~) and this path will be set each time each time you open a terminal. See here for a short introduction to .bashrc and other .bash* files. Hope that helps.
EDIT See also this question.

How do I use my standard python path when running python scripts from xcode macros

I'm trying to run Python scripts using Xcode's User Scripts menu.
The issue I'm having is that my usual os.sys.path (taken from ~/.profile) does not seem to be imported when running scripts from XCode the way it is when running them at the Terminal (or with IPython). All I get is the default path, which means I can't do things like
#!/usr/bin/python
import myScript
myScript.foo()
Where myScript is a module in a folder I've added to my path.
I can append a specific path to os.sys.path manually easily enough, but I have to do it in every single script for every single path I want to use modules from
Is there a way to set this up so it uses the same path I use everywhere else?
EDIT: After looking into things a bit more, it seems like scripts executed from Xcode use a completely different PATH than normal. The path I get by running a script in Xcode is:
PATH=/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin
and I'm sure my regular path doesn't have /Developer/usr/bin in it. Does anybody have any idea where this path is coming from?
On the mac, environment variables in your .profile aren't visible to applications outside of the terminal.
If you want an environment variable (like PATH, PYTHONPATH, etc) to be available to xcode apps, you should add it to a new plist file that you create at ~/.MacOSX/environment.plist.
See the EnvironmentVars doc on the apple developer website for more details.
A quick but hackish way is to have a wrapper script for python.
cat > $HOME/bin/mypython << EOF
#!/usr/bin/python
import os
os.path = ['/list/of/paths/you/want']
EOF
and then start all your XCode scripts with
#!/Users/you/bin/mypython
Just add the paths to sys,path.
>>> import sys
>>> sys.path
['', ... lots of stuff deleted....]
>>> for i in sys.path:
... print i
...
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python25.zip
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-darwin
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-mac
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-mac/lib-scriptpackages
/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-tk
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-dynload
/Library/Python/2.5/site-packages
/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/PyObjC
>>> sys.path.append("/Users/crm/lib")
>>> for i in sys.path:
... print i
...
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python25.zip
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-darwin
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-mac
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-mac/lib-scriptpackages
/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-tk
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-dynload
/Library/Python/2.5/site-packages
/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/PyObjC
/Users/crm/lib
>>>
I tend to use pth files. From the docs.
The most convenient way is to add a
path configuration file to a directory
that’s already on Python’s path,
usually to the .../site-packages/
directory. Path configuration files
have an extension of .pth, and each
line must contain a single path that
will be appended to sys.path. (Because
the new paths are appended to
sys.path, modules in the added
directories will not override standard
modules. This means you can’t use this
mechanism for installing fixed
versions of standard modules.)
So the simplest thing to do is to do the following:
echo "/some/path/I/want/to/add" > /Library/Python/2.5/site-packages/custom.pth
HTH
Forgive me if my answer seems ignorant, I'm not totally familiar with Mac and I also may have misunderstood your question.
On Windows and Linux, when I want to refer to a script I've written, I set the PYTHONPATH environment variable. It is what os.sys.path gets its values from, if I remember correctly.
Let's say myScript.py is in /Somewhere. Set PYTHONPATH to:
PYTHONPATH = /Somewhere
Now you should be able to "import myScript".
If you start doing sub-folders as python packages, look into usage of init.py files in each folder.
If you plan on re-using this and other scripts all the time, you should leave PYTHONPATH set as an environment variable.
Not sure if Xcode counts as launching the script through Finder or not, but if it does, apparently Finder doesn't read .profile or .cshrc files when it starts for a user the way Terminal does.
If your question is unanswered still, check out Apple's knowledge base: QA1067 and set up your environment using the plist.

Categories

Resources