[Tutor] running modules as scripts
Steven D'Aprano
steve at pearwood.info
Fri Dec 6 03:22:35 CET 2013
On Thu, Dec 05, 2013 at 01:20:05PM -0500, ugajin at talktalk.net wrote:
> I have some difficulty with the abovet. I succeeded after a fashion,
> but only after some experiment, and I am not satisfied that all is
> well. Here is the script code (as per the Python tutorial 6.1.1.):
> It is saved in the current directory as fibo.py with the current
> directory being:
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/
I doubt that is the current directory. Unless you type:
cd /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/
at the terminal, it won't be the current directory.
There are three important concepts for you to understand:
1) The Python path. This is a set of directories that Python will search
when *importing* a module. The Python path includes the location of
Python's standard library modules. As a general rule, you should not
mess with the standard library -- don't change the files there, don't
remove them, and don't add your own into the same location.
Instead, you should designate a folder in your home directory for your
own Python scripts, and put them all in that. For advanced users, you
can violate this rule -- the Python path is user-editable to allow that.
But you need to know what you are doing.
2) The current, or working, directory. This is a concept from the
operating system and shell, and Python inherits the concept from them.
Think of it as meaning "the directory (folder) you are currently in",
and at the terminal you change the working directory with the cd
command.
3) The path to a file, which may be an absolute path, or a relative
path. In Mac, Unix and Linux, absolute paths start with / (slash).
Relative paths do not, and are treated as relative from the current
working directory.
The end result is this: if you create a file called "fibo.py" and place
it somewhere in the Python path (including in Python's own standard
library, which is not a good idea), then you can import that module in
Python. You can also run that module with the -m switch by giving the
module name, which excludes the .py extension:
python -m fibo
and Python will search all the appropriate places for a module like
fibo.py or fibo.so or similar, import it, then run it as a script. This
will work wherever you are (the working directory), since it uses
Python's own search path for modules.
On the other hand, if you run a file directly, you need to give the path
to the file. You can give an absolute path:
python /home/ugajin/scripts/fibo.py # for example
or you can change the working directory and then give a relative path:
cd /home/ugajin/
python scripts/fibo.py
or
cd /home/ugajin/scripts
python fibo.py
or similar. Basically, if running ls shows you the file you want to run,
you can run it directly, otherwise you need to give a path to it.
So you can see, when you give a file name as argument, Python does not
search the sys.path to find the file, it needs to be given full
directions to reach it -- either as a path relative to the current
working directory (which you set with cd) or an absolute path starting
with a slash.
[...]
> And. . . if I open the same script with: right click > Open with > Python Launcher.app (2.7.6) I get:
> Last login: Wed Dec 4 20:52:15 on ttys002
> Apples-iMac-4:~ apple$ cd '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/' && '/usr/bin/pythonw' '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/fibo.py' && echo Exit status: $? && exit 1
> Traceback (most recent call last):
> File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/fibo.py", line 21, in <module>
> fib(int(sys.argv[1]))
> IndexError: list index out of range
This error is easy to explain: since you're running the script with the
right-click option, there's no command line arguments given, and
sys.argv is the empty list []. Since there are no items in sys.argv,
sys.argv[1] will fail with IndexError.
> Then . . . if I then use this same window to call the script it runs:
> Apples-iMac-4:python2.7 apple$ python fibo.py 50
> 1 1 2 3 5 8 13 21 34
And this succeeds because you have (inadvertently) changed the working
directory to the location of the file.
My recommendation is:
- In your home directory, create a folder called "scripts", and
put all *your* Python files in that. Leave Python's own files
where you found them.
- Do you know how to edit your shell's config files? On Linux,
I would say:
nano ~/.bashrc
but I'm not sure what the Mac equivalent is. In any case, edit
your config file to include the line:
export PYTHONPATH="/home/ugajin/scripts/"
(or whatever the path to your scripts directory actually is).
This is optional but will make importing scripts easier.
- After you have done this, then either of these lines ought to
work from any working directory:
python -m fibo 50
python ~/scripts/fibo.py 50
Feel free to ask any additional questions!
--
Steven
More information about the Tutor
mailing list