Re: os.path.join doubt
On Thu, 03 Feb 2011 06:31:49 +, Steven D'Aprano wrote: On Wed, 02 Feb 2011 20:46:12 -0800, harryos wrote: In windows ,I tried this p1 = C:\Users\me\Documents p2 = ..\Pictures\images\my.jpg Don't do this; backslash is significant within Python string literals. If want to use literal backslashes in a string literal, either double them: p1 = C:\\Users\\me\\Documents or use a raw literal: p1 = rC:\Users\me\Documents You got away with it because backslash is only significant when followed by specific characters, none of which occurred in this case. BTW, Windows accepts / as well as \ as a path separator. You will have far fewer headaches if you use that. Unless you need to pass strings to the command interpreter, which has its own interpretation of forward slashes. Apart from that, while forward slashes are supported by Windows itself, they aren't the standard separator, and may not be supported by other programs running on Windows. In general, directory separators shouldn't occur within string literals. Base directories should be taken from command-line parameters, registry entries, configuration files, environment variables etc, not embedded into the program. Paths relative to those directories should be constructed with os.path.join(). -- http://mail.python.org/mailman/listinfo/python-list
Re: os.path.join doubt
'C:\\Users\\me\\Documents\\..\\Pictures\\images\\my.jpg' is a valid path. .. means parent, not 'go back a directory'. But you should really be trying this: p1 = os.environ['HOMEPATH'] p2 = os.path.join(p1, 'Pictures', 'images', 'my.jpg') On Wed, 2011-02-02 at 20:46 -0800, harryos wrote: In windows ,I tried this p1 = C:\Users\me\Documents p2 = ..\Pictures\images\my.jpg print os.path.join(p1,p2) This gives 'C:\\Users\\me\\Documents\\..\\Pictures\\images\\my.jpg' I expected I would get 'C:\\Users\\me\\Pictures\\images\\my.jpg' I thought os.path.join would join the paths more intelligently..Any idea why this happens ? harry -- http://mail.python.org/mailman/listinfo/python-list
Re: os.path.join doubt
Steven D'Aprano wrote: BTW, Windows accepts / as well as \ as a path separator. You will have far fewer headaches if you use that. Just because Windows accepts / doesn't make it a good idea... Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on win32 Type help, copyright, credits or license for more information. -- from glob import glob -- print '\n'.join(glob('c:/temp/*')) c:/temp\0C2O0007.TMP c:/temp\27421 c:/temp\3K540007.TMP c:/temp\AIF19780_01B_BACKUP.DBF c:/temp\Arabic.bin c:/temp\au-descriptor-1.6.0_23-b71.xml c:/temp\AUCHECK_CORE.txt c:/temp\AUCHECK_PARSER.txt c:/temp\bar.py c:/temp\bar.pyc c:/temp\caller.py c:/temp\caller.pyc c:/temp\choose_python.pdf c:/temp\CMD19639_B_BACKUP.DBF c:/temp\COA.pdf c:/temp\compress.py c:/temp\compress.pyc c:/temp\control.dbf c:/temp\control.FPT Or is there an option I'm missing so backslashes are not returned by stdlib functions? ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: os.path.join doubt
On Thu, 03 Feb 2011 07:58:55 -0800, Ethan Furman wrote: Steven D'Aprano wrote: BTW, Windows accepts / as well as \ as a path separator. You will have far fewer headaches if you use that. Just because Windows accepts / doesn't make it a good idea... No. Windows accepting slashes as the alternate path separator *enables* you to use slash. What makes it a good idea is that you don't have to worry about forgetting to escape backslashes: print(C:\temp\file.txt) C: emp ile.txt Nor do you have to care about the fact that raw strings are designed for regular expressions, not Windows path names, and you can't have a raw string ending in a single backslash: location = r'C:\temp\' # Path ending in a backslash. File stdin, line 1 location = r'C:\temp\' ^ SyntaxError: EOL while scanning string literal The fact is that Windows' use of backslash as the path separator conflicts with Python's use of backslashes. Since our code is written in Python, trying to uses backslashes causes problems. One work-around is to take advantage of the fact that Windows has an alternate separator character, and use that. If you'd rather use raw strings, and special- case backslashes at the end of paths, go right ahead. -- from glob import glob -- print '\n'.join(glob('c:/temp/*')) c:/temp\0C2O0007.TMP c:/temp\27421 c:/temp\3K540007.TMP [...] Yes. Is there a problem? All those paths should be usable from Windows. If you find it ugly to see paths with a mix of backslashes and forward slashes, call os.path.normpath, or just do a simple string replace: path = path.replace('/', '\\') before displaying them to the user. Likewise if you have to pass the paths to some application that doesn't understand slashes. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: os.path.join doubt
On Thu, 2011-02-03 at 23:11 +, Steven D'Aprano wrote: On Thu, 03 Feb 2011 07:58:55 -0800, Ethan Furman wrote: Steven D'Aprano wrote: BTW, Windows accepts / as well as \ as a path separator. You will have far fewer headaches if you use that. Just because Windows accepts / doesn't make it a good idea... No. Windows accepting slashes as the alternate path separator *enables* you to use slash. What makes it a good idea is that you don't have to worry about forgetting to escape backslashes: print(C:\temp\file.txt) C: emp ile.txt Nor do you have to care about the fact that raw strings are designed for regular expressions, not Windows path names, and you can't have a raw string ending in a single backslash: location = r'C:\temp\' # Path ending in a backslash. File stdin, line 1 location = r'C:\temp\' ^ SyntaxError: EOL while scanning string literal The fact is that Windows' use of backslash as the path separator conflicts with Python's use of backslashes. Since our code is written in Python, trying to uses backslashes causes problems. One work-around is to take advantage of the fact that Windows has an alternate separator character, and use that. If you'd rather use raw strings, and special- case backslashes at the end of paths, go right ahead. -- from glob import glob -- print '\n'.join(glob('c:/temp/*')) c:/temp\0C2O0007.TMP c:/temp\27421 c:/temp\3K540007.TMP [...] Yes. Is there a problem? All those paths should be usable from Windows. If you find it ugly to see paths with a mix of backslashes and forward slashes, call os.path.normpath, or just do a simple string replace: path = path.replace('/', '\\') before displaying them to the user. Likewise if you have to pass the paths to some application that doesn't understand slashes. -- Steven Paths that mix /s and \s are NOT valid on Windows. In one of the setup.py scripts I wrote I had to write a function to collect the paths of data files for installation. On Windows it didn't work and it was driving me crazy. It wasn't until I realized os.path.join was joining the paths with \\ instead of / that I was able to fix it. def find_package_data(path): Recursively collect EVERY file in path to a list. oldcwd = os.getcwd() os.chdir(path) filelist = [] for path, dirs, filenames in os.walk('.'): for name in filenames: filename = ((os.path.join(path, name)).replace('\\', '/')) filelist.append(filename.replace('./', 'data/')) os.chdir(oldcwd) return filelist -- http://mail.python.org/mailman/listinfo/python-list
Re: os.path.join doubt
At 05:33 PM 2/3/2011, Westley Martínez wrote: On Thu, 2011-02-03 at 23:11 +, Steven D'Aprano wrote: On Thu, 03 Feb 2011 07:58:55 -0800, Ethan Furman wrote: Steven D'Aprano wrote: [snip] Yes. Is there a problem? All those paths should be usable from Windows. If you find it ugly to see paths with a mix of backslashes and forward slashes, call os.path.normpath, or just do a simple string replace: path = path.replace('/', '\\') before displaying them to the user. Likewise if you have to pass the paths to some application that doesn't understand slashes. -- Steven Paths that mix /s and \s are NOT valid on Windows. In one of the setup.py scripts I wrote I had to write a function to collect the paths of data files for installation. On Windows it didn't work and it was driving me crazy. It wasn't until I realized os.path.join was joining the paths with \\ instead of / that I was able to fix it. def find_package_data(path): Recursively collect EVERY file in path to a list. oldcwd = os.getcwd() os.chdir(path) filelist = [] for path, dirs, filenames in os.walk('.'): for name in filenames: filename = ((os.path.join(path, name)).replace('\\', '/')) filelist.append(filename.replace('./', 'data/')) os.chdir(oldcwd) return filelist Please check out os.path.normpath() as suggested. Example: import os s = r/hello\\there//yall\\foo.bar s '/hellothere//yallfoo.bar' v = os.path.normpath(s) v '\\hello\\there\\yall\\foo.bar' The idea behind os.path is to cater to the host OS. Thus os.path.normpath() will convert to the host's acceptable delimiters. That is, you didn't need the .replace(), but rather to more fully use the existing library to good advantage with .normpath(). However, note that delimiters becomes an issue only when directly accessing the host OS, such as when preparing command line calls or accessing native APIs. Within the Python library/environment, both '/' and '\' are acceptable. External use is a different matter. So, you need to be specific on how and where your paths are to be used. For instance os.chdir() will work fine with a mixture, but command line apps or native APIs will probably fail. -- http://mail.python.org/mailman/listinfo/python-list
Re: os.path.join doubt
On Thu, 2011-02-03 at 17:57 -0600, Thomas L. Shinnick wrote: At 05:33 PM 2/3/2011, Westley Martínez wrote: On Thu, 2011-02-03 at 23:11 +, Steven D'Aprano wrote: On Thu, 03 Feb 2011 07:58:55 -0800, Ethan Furman wrote: Steven D'Aprano wrote: [snip] Yes. Is there a problem? All those paths should be usable from Windows. If you find it ugly to see paths with a mix of backslashes and forward slashes, call os.path.normpath, or just do a simple string replace: path = path.replace('/', '\\') before displaying them to the user. Likewise if you have to pass the paths to some application that doesn't understand slashes. -- Steven Paths that mix /s and \s are NOT valid on Windows. In one of the setup.py scripts I wrote I had to write a function to collect the paths of data files for installation. On Windows it didn't work and it was driving me crazy. It wasn't until I realized os.path.join was joining the paths with \\ instead of / that I was able to fix it. def find_package_data(path): Recursively collect EVERY file in path to a list. oldcwd = os.getcwd() os.chdir(path) filelist = [] for path, dirs, filenames in os.walk('.'): for name in filenames: filename = ((os.path.join(path, name)).replace('\\', '/')) filelist.append(filename.replace('./', 'data/')) os.chdir(oldcwd) return filelist Please check out os.path.normpath() as suggested. Example: import os s = r/hello\\there//yall\\foo.bar s '/hellothere//yallfoo.bar' v = os.path.normpath(s) v '\\hello\\there\\yall\\foo.bar' The idea behind os.path is to cater to the host OS. Thus os.path.normpath() will convert to the host's acceptable delimiters. That is, you didn't need the .replace(), but rather to more fully use the existing library to good advantage with .normpath(). However, note that delimiters becomes an issue only when directly accessing the host OS, such as when preparing command line calls or accessing native APIs. Within the Python library/environment, both '/' and '\' are acceptable. External use is a different matter. So, you need to be specific on how and where your paths are to be used. For instance os.chdir() will work fine with a mixture, but command line apps or native APIs will probably fail. The reason why I use replace instead of normpath is because I want it to '/'s on ALL platforms. This is because distutils requires the use of '/'s. -- http://mail.python.org/mailman/listinfo/python-list
Re: os.path.join doubt
On Wed, Feb 2, 2011 at 8:46 PM, harryos oswald.ha...@gmail.com wrote: In windows ,I tried this p1 = C:\Users\me\Documents p2 = ..\Pictures\images\my.jpg print os.path.join(p1,p2) This gives 'C:\\Users\\me\\Documents\\..\\Pictures\\images\\my.jpg' I expected I would get 'C:\\Users\\me\\Pictures\\images\\my.jpg' I thought os.path.join would join the paths more intelligently..Any idea why this happens ? Because that's just not how the function is defined. I admit the intelligently descriptor in its docs is fairly vague. Call os.path.normpath() on the join() result to simplify the path and obtain the form you expected. http://docs.python.org/library/os.path.html#os.path.normpath Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: os.path.join doubt
On Wed, 02 Feb 2011 20:46:12 -0800, harryos wrote: In windows ,I tried this p1 = C:\Users\me\Documents p2 = ..\Pictures\images\my.jpg print os.path.join(p1,p2) This gives 'C:\\Users\\me\\Documents\\..\\Pictures\\images\\my.jpg' I expected I would get 'C:\\Users\\me\\Pictures\\images\\my.jpg' I thought os.path.join would join the paths more intelligently..Any idea why this happens ? You thought wrong. os.path.join just joins what you tell it to, it doesn't normalise the path. If you want to normalise, call os.path.normpath: os.path.normpath('x/y/../z') 'x/z' As for why, it's because joining and normalising are two different operations that you may wish to keep separate, so they require two separate functions. BTW, Windows accepts / as well as \ as a path separator. You will have far fewer headaches if you use that. -- Steven -- http://mail.python.org/mailman/listinfo/python-list