What's the Scoop on \\ for Paths? (Win)

Discussion in 'Python' started by W. eWatson, Jan 31, 2010.

  1. W. eWatson

    W. eWatson Guest

    I'm sure that \\ is used in some way for paths in Win Python, but I have
    not found anything after quite a search. I even have a six page pdf on a
    file tutorial. Nothing. Two books. Nothing. When I try to open a file
    along do I need, for example, "Events\\record\\year\\today"? Are paths
    like, ".\\Events" allowed, or am I mixing up my Linux memory on this?
     
    W. eWatson, Jan 31, 2010
    #1
    1. Advertising

  2. * W. eWatson:
    > I'm sure that \\ is used in some way for paths in Win Python, but I have
    > not found anything after quite a search. I even have a six page pdf on a
    > file tutorial. Nothing. Two books. Nothing. When I try to open a file
    > along do I need, for example, "Events\\record\\year\\today"? Are paths
    > like, ".\\Events" allowed, or am I mixing up my Linux memory on this?


    The Python issue with \\ is that in a literal string \\ denotes a single \
    character, like

    >>> print( "back\\slash" )

    back\slash
    >>> _


    This is just like in other languages with syntax inherited from C. Look up
    "escape sequences". It has nothing to do with files and paths per se, but means
    that you cannot write e.g. "c:\windows\system32", but must write something like
    "c:\\windows\\system32" (try to print that string), or, since Windows handles
    forward slashes as well, you can write "c:/windows/system32" :).

    The Window issue with \\ is that \\ as a path prefix denotes an UNC (Universal
    Naming Convention) path. Usually that would be a LAN or WAN network path, but it
    can also denote a printer or a pipe or a mailslot or just about anything. Using
    UNC paths opens the door to creating files and directories that other programs
    won't be able to handle, so Just Say No(TM), if you can.


    Cheers & hth.,

    - Alf
     
    Alf P. Steinbach, Jan 31, 2010
    #2
    1. Advertising

  3. W. eWatson

    Steve Holden Guest

    W. eWatson wrote:
    > I'm sure that \\ is used in some way for paths in Win Python, but I have
    > not found anything after quite a search. I even have a six page pdf on a
    > file tutorial. Nothing. Two books. Nothing. When I try to open a file
    > along do I need, for example, "Events\\record\\year\\today"? Are paths
    > like, ".\\Events" allowed, or am I mixing up my Linux memory on this?


    You need to read up on string literals is all. "\\" is simply the
    literal representation of a string containing a single backslash. This
    comes about because string literals are allowed to contain special
    "escape sequences" which are introduced by a backslash; since this gives
    the backslash a special meaning in string literals we also have to use
    an escape sequence ("\\") to represent a backslash.

    In practice you will find that

    a) Many Windows APIs (but not the command line) are just as happy with a
    forward slash as a backslash to separate file path components; and

    b) The best practice is to build filenames using the routines provided
    in the os.path module, which guarantees to give results correct for the
    current platform.

    regards
    Steve
    --
    Steve Holden +1 571 484 6266 +1 800 494 3119
    PyCon is coming! Atlanta, Feb 2010 http://us.pycon.org/
    Holden Web LLC http://www.holdenweb.com/
    UPCOMING EVENTS: http://holdenweb.eventbrite.com/
     
    Steve Holden, Jan 31, 2010
    #3
  4. W. eWatson

    Steve Holden Guest

    W. eWatson wrote:
    > I'm sure that \\ is used in some way for paths in Win Python, but I have
    > not found anything after quite a search. I even have a six page pdf on a
    > file tutorial. Nothing. Two books. Nothing. When I try to open a file
    > along do I need, for example, "Events\\record\\year\\today"? Are paths
    > like, ".\\Events" allowed, or am I mixing up my Linux memory on this?


    You need to read up on string literals is all. "\\" is simply the
    literal representation of a string containing a single backslash. This
    comes about because string literals are allowed to contain special
    "escape sequences" which are introduced by a backslash; since this gives
    the backslash a special meaning in string literals we also have to use
    an escape sequence ("\\") to represent a backslash.

    In practice you will find that

    a) Many Windows APIs (but not the command line) are just as happy with a
    forward slash as a backslash to separate file path components; and

    b) The best practice is to build filenames using the routines provided
    in the os.path module, which guarantees to give results correct for the
    current platform.

    regards
    Steve
    --
    Steve Holden +1 571 484 6266 +1 800 494 3119
    PyCon is coming! Atlanta, Feb 2010 http://us.pycon.org/
    Holden Web LLC http://www.holdenweb.com/
    UPCOMING EVENTS: http://holdenweb.eventbrite.com/
     
    Steve Holden, Jan 31, 2010
    #4
  5. W. eWatson

    W. eWatson Guest

    Alf P. Steinbach wrote:
    > * W. eWatson:
    >> I'm sure that \\ is used in some way for paths in Win Python, but I
    >> have not found anything after quite a search. I even have a six page
    >> pdf on a file tutorial. Nothing. Two books. Nothing. When I try to
    >> open a file along do I need, for example,
    >> "Events\\record\\year\\today"? Are paths like, ".\\Events" allowed, or
    >> am I mixing up my Linux memory on this?

    >
    > The Python issue with \\ is that in a literal string \\ denotes a single
    > \ character, like
    >
    > >>> print( "back\\slash" )

    > back\slash
    > >>> _

    >
    > This is just like in other languages with syntax inherited from C. Look
    > up "escape sequences". It has nothing to do with files and paths per se,
    > but means that you cannot write e.g. "c:\windows\system32", but must
    > write something like "c:\\windows\\system32" (try to print that string),
    > or, since Windows handles forward slashes as well, you can write
    > "c:/windows/system32" :).
    >
    > The Window issue with \\ is that \\ as a path prefix denotes an UNC
    > (Universal Naming Convention) path. Usually that would be a LAN or WAN
    > network path, but it can also denote a printer or a pipe or a mailslot
    > or just about anything. Using UNC paths opens the door to creating files
    > and directories that other programs won't be able to handle, so Just Say
    > No(TM), if you can.
    >
    >
    > Cheers & hth.,
    >
    > - Alf

    Ah, yes. Thanks for the memory jog.
     
    W. eWatson, Jan 31, 2010
    #5
  6. W. eWatson

    W. eWatson Guest

    Steve Holden wrote:

    > You need to read up on string literals is all. "\\" is simply the
    > literal representation of a string containing a single backslash. This
    > comes about because string literals are allowed to contain special
    > "escape sequences" which are introduced by a backslash; since this gives
    > the backslash a special meaning in string literals we also have to use
    > an escape sequence ("\\") to represent a backslash.
    >
    > In practice you will find that
    >
    > a) Many Windows APIs (but not the command line) are just as happy with a
    > forward slash as a backslash to separate file path components; and
    >
    > b) The best practice is to build filenames using the routines provided
    > in the os.path module, which guarantees to give results correct for the
    > current platform.
    >
    > regards
    > Steve

    Basic sys functions brought out the \ separator for paths.

    What am I missing here? Looks OK to me.


    >>> abc=r'xyz\\'
    >>> abc

    'xyz\\\\'
    >>> print abc

    xyz\\
    >>> abc.replace(r'\',r'z')


    SyntaxError: invalid syntax
    >>> abc

    'xyz\\\\'
     
    W. eWatson, Jan 31, 2010
    #6
  7. W. eWatson

    Steve Holden Guest

    W. eWatson wrote:
    > Steve Holden wrote:
    >
    >> You need to read up on string literals is all. "\\" is simply the
    >> literal representation of a string containing a single backslash. This
    >> comes about because string literals are allowed to contain special
    >> "escape sequences" which are introduced by a backslash; since this gives
    >> the backslash a special meaning in string literals we also have to use
    >> an escape sequence ("\\") to represent a backslash.
    >>
    >> In practice you will find that
    >>
    >> a) Many Windows APIs (but not the command line) are just as happy with a
    >> forward slash as a backslash to separate file path components; and
    >>
    >> b) The best practice is to build filenames using the routines provided
    >> in the os.path module, which guarantees to give results correct for the
    >> current platform.
    >>
    >> regards
    >> Steve

    > Basic sys functions brought out the \ separator for paths.
    >
    > What am I missing here? Looks OK to me.
    >
    >
    >>>> abc=r'xyz\\'
    >>>> abc

    > 'xyz\\\\'
    >>>> print abc

    > xyz\\
    >>>> abc.replace(r'\',r'z')

    >
    > SyntaxError: invalid syntax
    >>>> abc

    > 'xyz\\\\'


    The SyntaxError is thrown because although backslashes lose their
    special "escape sequence" meaning, for some reason I have never really
    understood they retain the requirement that they be followed by another
    character.

    abc.replace("\\", 'z')

    would have worked fine.

    regards
    Steve
    --
    Steve Holden +1 571 484 6266 +1 800 494 3119
    PyCon is coming! Atlanta, Feb 2010 http://us.pycon.org/
    Holden Web LLC http://www.holdenweb.com/
    UPCOMING EVENTS: http://holdenweb.eventbrite.com/
     
    Steve Holden, Jan 31, 2010
    #7
  8. W. eWatson

    MRAB Guest

    W. eWatson wrote:
    > Steve Holden wrote:
    >
    >> You need to read up on string literals is all. "\\" is simply the
    >> literal representation of a string containing a single backslash. This
    >> comes about because string literals are allowed to contain special
    >> "escape sequences" which are introduced by a backslash; since this gives
    >> the backslash a special meaning in string literals we also have to use
    >> an escape sequence ("\\") to represent a backslash.
    >>
    >> In practice you will find that
    >>
    >> a) Many Windows APIs (but not the command line) are just as happy with a
    >> forward slash as a backslash to separate file path components; and
    >>
    >> b) The best practice is to build filenames using the routines provided
    >> in the os.path module, which guarantees to give results correct for the
    >> current platform.
    >>
    >> regards
    >> Steve

    > Basic sys functions brought out the \ separator for paths.
    >
    > What am I missing here? Looks OK to me.
    >
    >
    > >>> abc=r'xyz\\'
    > >>> abc

    > 'xyz\\\\'
    > >>> print abc

    > xyz\\
    > >>> abc.replace(r'\',r'z')

    >
    > SyntaxError: invalid syntax
    > >>> abc

    > 'xyz\\\\'


    It's not possible to end a raw string with a single backslash, and if
    you end it with a double backslash then you'll get a double backslash.
    Very annoying.
     
    MRAB, Jan 31, 2010
    #8
  9. * Tim Chase:
    > Alf P. Steinbach wrote:
    >> that you cannot write e.g. "c:\windows\system32", but must
    >> write something like "c:\\windows\\system32" (try to print
    >> that string), or, since Windows handles forward slashes as
    >> well, you can write "c:/windows/system32" :).

    >
    > Forward slashes work for some relative paths for some commands but not
    > for others like absolute non-drive-specified paths:
    >
    > Microsoft Windows XP [Version 5.1.2600]
    > C:\>md abc
    > C:\>md abc\123
    > C:\>md abc\234
    > C:\>cd abc
    > C:\abc>tree /f /a
    > Folder PATH listing
    > Volume serial number is 940C-3F80
    > C:.
    > +---123
    > | \---234
    > \---234
    >
    > C:\abc>cd 123
    > C:\abc\123>cd ../234
    > C:\abc\234>type ../123/234/hello.txt
    > The syntax of the command is incorrect.
    > C:\abc\234>cd ../123
    > C:\abc\123>cd /abc/123
    > The system cannot find the path specified.
    > C:\abc>x:
    > X:\>type c:/abc/123/234/hello.txt
    > The syntax of the command is incorrect.
    >
    > #####
    > The previous absolute-path fails in cmd.exe for a variety of apps
    > because the "/" is treated as a parameter/switch to the various
    > programs.


    Yes, that's a valid concern when invoking external programs.


    > Fortunately, the Python path-handling sub-system is smart
    > enough to do the right thing, even when Win32's internal handling is too
    > dumb to behave:
    >
    > C:\abc\123>echo hello > 234/hello.txt
    > C:\abc\123>cd ..
    > C:\abc>tree /f /a
    > Folder PATH listing
    > Volume serial number is 940C-3F80
    > C:.
    > +---123
    > | \---234
    > | hello.txt
    > |
    > \---234
    >
    > C:\abc>python
    > Python 2.4.3 (#69, Mar 29 2006, 17:35:34) [MSC v.1310 32 bit (Intel)] on
    > win32
    > Type "help", "copyright", "credits" or "license" for more information.
    > >>> file('/abc/123/234/hello.txt').read()

    > 'hello \n'


    Oops, this is a dangerous misconception, because it can lead to Wrong Solutions
    to the perceived problems.

    It's not the "Win32's internal handling" that you're up against above, but the
    generally unpredictable quirks of syntax and semantics of commands in the
    Windows command interpreter:

    <example>
    C:\test> echo bah >foo.txt

    C:\test> type ../test/foo.txt
    The syntax of the command is incorrect.

    C:\test> type "../test/foo.txt"
    bah

    C:\test> _
    </example>

    Generally the details of that command interpreter are undocumented.


    > So as long as you stick within Python's insulation, forward slashes are
    > a nice solution.


    No, it's not Python's insulation that makes things work (although perhaps it
    redundantly tries to help), it's simply the Windows API, which generally accepts
    forward or backward slashes.

    It's the same in other programming languages.

    In particular, it's not a good idea to carry the idea of using backslashes over
    to #include directives in C or C++, thinking that there's no Python insulation
    there (at least one compiler accepts and Windows compilers used to accept it at
    one time, but it's invalid, and non-portable, whereas forward slashes work).


    > But if you have to interact with external programs,
    > use the \\ notation or raw strings:
    >
    > pth = r"c:\windows\system32"
    >
    > [mutters under breath about Win32 headaches]


    He he. Yes.

    But anyways, the thing to remember is that when paths are passed to /programs/
    in Windows, they generally need to be /quoted/.

    That's particularly important for paths containing spaces.

    For internal file handling in a program, including using libraries, forward
    slashes work fine -- unless a library is particularly ill-behaved and requires
    backslashes -- and provide some (but not complete) measure of portability.

    For example,


    <example>
    >>> f = open( "c:/foo.txt", "w" )
    >>> f.write( "works\n" )

    6
    >>> f.close()
    >>> f = open( "c:/foo.txt", "r" )
    >>> f.readlines()

    ['works\n']
    >>> f.close()
    >>> _

    </example>


    In retrospect, I should have been more clear about that distinction between
    invoking programs and invoking routines such as Python 'open', yes.

    And as Steve Holden remarked else-thread, best practice for Python is to build
    paths using the os.path functionality.

    E.g.,


    <example>
    >>> import os.path
    >>> os.path.normpath( "c:/foo.txt" )

    'c:\\foo.txt'
    >>> _

    </example>


    Cheers & hth.,

    - Alf
     
    Alf P. Steinbach, Jan 31, 2010
    #9
  10. W. eWatson

    Nobody Guest

    On Sun, 31 Jan 2010 13:41:55 -0600, Tim Chase wrote:

    > The previous absolute-path fails in cmd.exe for a variety of apps because
    > the "/" is treated as a parameter/switch to the various programs.
    > Fortunately, the Python path-handling sub-system is smart enough to do the
    > right thing, even when Win32's internal handling is too dumb to behave:


    Let's not conflate multiple issues:

    1. Windows API functions almost invariably accept either \ or /.

    2. Python functions just pass filename strings verbatim; they won't try to
    "fix" them in cases where a specific separator is required (e.g. system(),
    which calls cmd.exe or %COMSPEC%, which has its own requirements).

    3. Command-line programs may treat / as indicating a switch, even in what
    would normally be considered the middle of an argument.

    4. Windows doesn't enforce the "char **argv" convention. Programs get
    passed the literal command line as a single string, and are free to parse
    it however they wish.

    4a. Programs compiled with MSVC and using a main(argc, argv) interface
    will have the command-line parsed as documented in:

    http://msdn.microsoft.com/en-us/library/17w5ykft.aspx

    Programs built with other compilers, programs using WinMain(), and
    programs which use the "raw" command line may behave differently, and
    certain Windows command-line programs (most notably those inherited from
    DOS) *do* behave differently.

    5. Python functions which accept command arguments as a list of strings
    (e.g. subprocess.call()) will assemble a command string according to the
    above specification. If you're invoking a program which doesn't follow
    that specification, you'll need to pass the command-line as a string
    rather than as a list of arguments.
     
    Nobody, Jan 31, 2010
    #10
  11. On Sun, 31 Jan 2010 13:41:55 -0600, Tim Chase
    <> declaimed the following in
    gmane.comp.python.general:


    > So as long as you stick within Python's insulation, forward
    > slashes are a nice solution. But if you have to interact with
    > external programs, use the \\ notation or raw strings:
    >
    > pth = r"c:\windows\system32"
    >
    > [mutters under breath about Win32 headaches]
    >

    Or use something that should be safe on any OS... and normalize the
    path before using it.

    >>> somepath = "c:/here/I/am\or/not"
    >>> print somepath

    c:/here/I/am\or/not
    >>> import os.path
    >>> print os.path.normpath(somepath)

    c:\here\I\am\or\not
    >>>

    --
    Wulfraed Dennis Lee Bieber KD6MOG
    HTTP://wlfraed.home.netcom.com/
     
    Dennis Lee Bieber, Jan 31, 2010
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tony Lavinio
    Replies:
    0
    Views:
    555
    Tony Lavinio
    Jan 26, 2005
  2. ARaman
    Replies:
    1
    Views:
    408
    Mike Wahler
    Oct 23, 2003
  3. Noah
    Replies:
    5
    Views:
    848
  4. Krist
    Replies:
    6
    Views:
    803
    Arne Vajhøj
    May 7, 2010
  5. Ohad Lutzky

    Paths, gentleman, paths

    Ohad Lutzky, Nov 6, 2006, in forum: Ruby
    Replies:
    2
    Views:
    225
    David Vallner
    Nov 7, 2006
Loading...

Share This Page