[Tutor] slashes in paths

eryksun eryksun at gmail.com
Sat Jul 20 23:16:01 CEST 2013


> soundpath = 'c:/python27/jimprogs/wav'
> soundlist = os.listdir(soundpath)
> soundfile13 = os.path.join(soundpath, soundlist[13])
>
>>>> soundfile13
> 'c:/python27/jimprogs/wav\\bicycle_bell.wav'

You can use os.path.normpath() to make it consistent:

    >>> soundpath = 'c:/python27/jimprogs/wav\\bicycle_bell.wav'

    >>> print os.path.normpath(soundpath)
    c:\python27\jimprogs\wav\bicycle_bell.wav


> Oddly, the mixed path does work for playing sounds

The NT runtime library takes care of translating the path, such as
converting slash to backslash, ignoring repeated slashes, handling
"..", and so on.

NT itself uses backslashes. For exmaple, if you need to use the \\?\
prefix to get around the 260-character path limit, you have to use an
absolute path that only uses backslash. This bypasses the normal
translation and lets you access paths that are over 30,000 characters
long.

Here's an example that directly calls the library function used to
translate a DOS-style path: RtlDosPathNameToNtPathName_U. It's
exported from ntdll.dll (lovely name that is):

Some ctypes defintions:

    from ctypes import *

    dos_to_nt = windll.ntdll.RtlDosPathNameToNtPathName_U

    # we need a buffer for the result
    class UNICODE_STRING(Structure):
        _fields_ = [
            ('Length', c_ushort),
            ('MaximumLength', c_ushort),
            ('Buffer', POINTER(c_wchar)),
        ]

    ntpath = UNICODE_STRING()


    >>> soundpath = u'c:/python27/jimprogs/wav\\bicycle_bell.wav'

    >>> dos_to_nt(soundpath, byref(ntpath), None, None)
    1
    >>> ntpath.Length // 2  # length in bytes, not wchar_t
    45
    >>> print ntpath.Buffer[:45]
    \??\c:\python27\jimprogs\wav\bicycle_bell.wav

The \?? prefix is the directory in NT's object namespace where it
keeps symbolic links for DOS device names. If you have WinObj from
sysinterals, take a look in "\GLOBAL??". You'll see that C: is a
symbolic link, usually to the NT native path \Device\HarddiskVolume1.

http://technet.microsoft.com/en-us/sysinternals/bb896657.aspx

> It does work right if I end the path with a / - i.e. - soundpath =
> 'c:/python27/jimprogs/wav/' but that's not required. Ending with a
> forward slash or  not seems to work either way, although I'm not sure
> about Linux.

If the path already ends in a '/' or '\', then ntpath.join
(os.path.join) just appends to the existing separator:

http://hg.python.org/cpython/file/ab05e7dd2788/Lib/ntpath.py#l94


More information about the Tutor mailing list