Python 3 minor irritation
benjamin.kaplan at case.edu
Thu Feb 4 05:41:00 CET 2010
On Wed, Feb 3, 2010 at 11:18 PM, Alf P. Steinbach <alfps at start.no> wrote:
> * Benjamin Kaplan:
>> On Wed, Feb 3, 2010 at 9:56 PM, Alf P. Steinbach <alfps at start.no> wrote:
>>> * David Monaghan:
>>>> I have a small program which reads files from the directory in which it
>>>> resides. It's written in Python 3 and when run through IDLE or PythonWin
>>>> works fine. If I double-click the file, it works fine in Python 2.6, but
>>>> 3 it fails because it looks for the files to load in the Python31
>>>> not the one the script is in.
>>>> It's not a big deal, but browsing around I haven't found why the
>>>> has been changed or any comment about it (That might be my poor search
>>>> technique, I suppose).
>>>> The program fails at:
>>>> tutdoc = minidom.parse(".//Myfile.xml")
>>>> except IOError:
>>> The "//" is wrong, but should not cause the behavior that you describe.
>>> Try to post a complete smallest possible program that exhibits the
>>> Possibly, in creating that example you'll also find what's cause the
>>> problem. :-)
>>> Cheers & hth.,
>>> - Alf
>> That is the smallest example the exhibits the problem.
> No, it doesn't seem to exhibit the problem at all. :-)
>> It's not an
>> issue with the Python code, it's an issue with how Windows is running
>> it. I don't know enough about the way Windows Explorer runs files, but
>> it seems to be doing the equivalent of
>> cd C:\Python31
>> python31.exe C:\full\path\to\script\foo.py
>> instead of
>> cd C:\full\path\path\to\script
>> C:\Python31\python.exe foo.py
>> which is David expected. This throws off the relative filepath.
> No, this is not what happens.
> What happens is that when you double-click the script, then __file__ is set
> to the absolute path instead of just the filename, at least on my machine
> (XP); whether the full path or just the filename is passed on the OS level
> depends, however, on the Windows version.
> The current directory is always (initially) correct, as the script's
Read my first paragraph again- it has absolutely nothing to do with
Python. It has to do with how the Windows is running Python 3 on the
OP's computer. The OP's description said that it was looking for the
file .\\myfile.xml in C:\Python31 which means it translated '.', the
current working directory, to be C:\Python31 and not the directory the
script is in.
>> The easiest way to solve this permanently, by the way, is to not use
>> relative paths. All it takes is one script to call os.chdir and the
>> script breaks. You can use __file__ and the os.path module to figure
>> out exactly where you are in an OS-agnostic way.
>> import os.path
>> #get the absolute path to the current script
>> abs_path = os.path.abspath(__file__)
> According to the docs: "On most platforms, this is equivalent to
> normpath(join(os.getcwd(), path))."
os.path.abspath will always work in this case (unless something
changes the current working directory before that statement runs)
because __file__ is given either as an absolute path or as relative to
the current working directory.
$ cd /users/bkaplan
$ python3 test/test.py
$ python3 test.py
If abspath is given an absolute path, it won't touch it
Output from double clicking on the file:
> Therefore, if getcwd() is not the script's directory, as you hypothesize
> above, then most likely the result of this code is Not The Path You're
> Looking For.
Except that if the cwd is not the directory the script is running in,
__file__ should still point to it either through an absolute path
(highly likely since it's run through Windows Explorer) or some
(however convoluted) relative path.
> However, since the current directory is in fact OK, the above is one way to
> get a sort of canonical (a where-you-know-the-format) representation of
>> # get the full path to the directory of the script
>> directory = os.path.dirname(abs_path)
> This is very much likely to yield the same result as calling os.getcwd();
> see above.
Not if there is more than one folder between __file__ and cwd. For
instance, if the script is in a package several directories down from
the main script.
>> #get the full path to your file
>> my_file = os.path.join(directory, "MyFile.xml")
> Cheers & hth.,
> - Alf
More information about the Python-list