However, os.path.abspath('b') gives me '/private/tmp/abspath/b', but
os.path.abspath('/tmp/abspath/b') gives me '/tmp/abspath/b'.
The results are not the same. So, neither os.path.abspath or
os.path.realpath gives me what I want.
I'm wondering if there is a way to get the canonical path
'/private/tmp/abspath/b', no matter whether the argument is 'b' or
'/tmp/abspath/b'.
$./test.py
/private/tmp/abspath/a
/private/tmp/abspath/a
/private/tmp/abspath/a
/private/tmp/abspath/a
/private/tmp/abspath/a
/private/tmp/abspath/b
/tmp/abspath/a
/tmp/abspath/b
$cat test.py
#!/usr/bin/env python
import os.path
print os.path.realpath('a')
print os.path.realpath('b')
print os.path.realpath('/tmp/abspath/a')
print os.path.realpath('/tmp/abspath/b')
print os.path.abspath('a')
print os.path.abspath('b')
print os.path.abspath('/tmp/abspath/a')
print os.path.abspath('/tmp/abspath/b')
$pwd
/tmp/abspath
$gls -Rgtra
.:
total 8
-rw-r--r-- 1 wheel 0 2009-10-31 01:52 a
lrwxr-xr-x 1 wheel 1 2009-10-31 01:52 b -> a
-rwx--x--x 1 wheel 312 2009-10-31 01:54 test.py
drwx------ 5 wheel 170 2009-10-31 01:54 .
drwxrwxrwt 23 wheel 782 2009-10-31 01:56 ..
$gls -lgtr /tmp
lrwxr-xr-x 1 admin 11 2009-05-21 04:28 /tmp -> private/tmp
So, why isn't realpath working for you? It looks like it is, and it
works that way here:
>>> os.path.realpath('/home/emile/vmlinuz')
'/root/vmlinuz-2.4.7-10'
Emile
My definition of 'realpath' is different from the definition of
'os.path.realpath'. But I'm not short what term I should use to
describe. I use the following example to show what I want.
In my example in the original post,
'/tmp/abspath/b' is a symbolic link to '/tmp/abspath/a' and '/tmp' is
a symbolic link to '/private/tmp'.
Therefore, I want to get '/private/tmp/abspath/b', rather than
'/private/tmp/abspath/a', as the canonical path of 'b'.
If the argument is a symbolic link os.path.realpath will return the
actually target of the symbolic link. However, I want the path of the
symbolic link rather than the path of the target.
Hope this is clear.
It still looks like it works here. I've set up a similar structure and
appear to get the results you're asking for using os.path.realpath.
# pwd
/home/emile
# ls -l
drwxr-xr-x 3 root root 4096 2009-10-31 10:25 private
lrwxrwxrwx 1 root root 11 2009-10-31 10:25 tmp -> private/tmp
# pwd
/home/emile/tmp/abspath
# ls -l
-rw-r--r-- 1 root root 10 2009-10-31 10:25 a
lrwxrwxrwx 1 root root 1 2009-10-31 10:26 b -> a
Python 2.6.3 (r263:75183, Oct 15 2009, 15:03:49) [GCC 4.3.2] on linux2
>>> import os
>>> os.path.realpath('/home/emile/tmp/a')
'/home/emile/private/tmp/a'
>>> os.path.realpath('/home/emile/tmp/b')
'/home/emile/private/tmp/b'
> If the argument is a symbolic link os.path.realpath will return the
> actually target of the symbolic link.
> However, I want the path of the
> symbolic link rather than the path of the target.
Which is what I got above.
>
> Hope this is clear.
I suspect that you will have to write your own code for your own
function. os and os.path are written in Python, so look at the code for
realpath and modify it for your modified definition.
Terry Jan Reedy
I'm curious why we get different results. I tried on both linux and
mac. Both of them give me the same results.
I find the following two files that define realpath. But I don't find
'realpath' in os.py. I looked at 'os.py'. But I don't understand how
the function realpath is introduced in the name space in os.path.
Would you please let me know?
gfind . ! -path '*backup*' -name "*.py" -type f -exec grep -n "def
realpath" {} \; -printf %p\\n\\n
193:def realpath(path):
./macpath.py
345:def realpath(filename):
./posixpath.py
> I find the following two files that define realpath. But I don't find
> 'realpath' in os.py. I looked at 'os.py'. But I don't understand how
> the function realpath is introduced in the name space in os.path.
> Would you please let me know?
> gfind . ! -path '*backup*' -name "*.py" -type f -exec grep -n "def
> realpath" {} \; -printf %p\\n\\n
> 193:def realpath(path):
> ./macpath.py
>
> 345:def realpath(filename):
> ./posixpath.py
The os module needs to support different platforms. The os.path module
is actually one of the platform specific ones (ntpath, posixpath,
...) that are imported 'as path' depending on the platform the code is
executed.
Have a look at the source code of the os module:
--- os.py - Python 2.6.3 ---
...
f 'posix' in _names:
...
import posixpath as path
elif 'nt' in _names:
...
import ntpath as path
import nt
__all__.extend(_get_exports_list(nt))
del nt
...
else:
raise ImportError, 'no os specific module found'
sys.modules['os.path'] = path
--- snip ---
If you really want to understand how a module is working then have a
look at its source code. Python is open source --> Use that privilige!
kind regards
Wolodja Wentland
> I find the following two files that define realpath. But I don't find
> 'realpath' in os.py. I looked at 'os.py'. But I don't understand how
> the function realpath is introduced in the name space in os.path.
> Would you please let me know?
>
> gfind . ! -path '*backup*' -name "*.py" -type f -exec grep -n "def
> realpath" {} \; -printf %p\\n\\n
> 193:def realpath(path):
> ./macpath.py
>
> 345:def realpath(filename):
> ./posixpath.py
That is where realpath is.