Python os.path.join on Windows

£可爱£侵袭症+ 提交于 2019-11-26 03:35:44

问题


I am trying to learn python and am making a program that will output a script. I want to use os.path.join, but am pretty confused. According to the docs if I say:

os.path.join(\'c:\', \'sourcedir\')

I get \"C:sourcedir\". According to the docs, this is normal, right?

But when I use the copytree command, Python will output it the desired way, for example:

import shutil
src = os.path.join(\'c:\', \'src\')
dst = os.path.join(\'c:\', \'dst\')
shutil.copytree(src, dst)

Here is the error code I get:

WindowsError: [Error 3] The system cannot find the path specified: \'C:src/*.*\'

If I wrap the os.path.join with os.path.normpath I get the same error.

If this os.path.join can\'t be used this way, then I am confused as to its purpose.

According to the pages suggested by Stack Overflow, slashes should not be used in join—that is correct, I assume?


回答1:


Windows has a concept of current directory for each drive. Because of that, "c:sourcedir" means "sourcedir" inside the current C: directory, and you'll need to specify an absolute directory.

Any of these should work and give the same result, but I don't have a Windows VM fired up at the moment to double check:

"c:/sourcedir"
os.path.join("/", "c:", "sourcedir")
os.path.join("c:/", "sourcedir")



回答2:


To be even more pedantic, the most python doc consistent answer would be:

mypath = os.path.join('c:', os.sep, 'sourcedir')

Since you also need os.sep for the posix root path:

mypath = os.path.join(os.sep, 'usr', 'lib')



回答3:


The reason os.path.join('C:', 'src') is not working as you expect is because of something in the documentation that you linked to:

Note that on Windows, since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\foo.

As ghostdog said, you probably want mypath=os.path.join('c:\\', 'sourcedir')




回答4:


To be pedantic, it's probably not good to hardcode either / or \ as the path separator. Maybe this would be best?

mypath = os.path.join('c:%s' % os.sep, 'sourcedir')

or

mypath = os.path.join('c:' + os.sep, 'sourcedir')



回答5:


For a system-agnostic solution that works on both Windows and Linux, no matter what the input path, one could use os.path.join(os.sep, rootdir + os.sep, targetdir)

On WIndows:

>>> os.path.join(os.sep, "C:" + os.sep, "Windows")
'C:\\Windows'

On Linux:

>>> os.path.join(os.sep, "usr" + os.sep, "lib")
'/usr/lib'



回答6:


I'd say this is a (windows)python bug.

Why bug?

I think this statement should be True

os.path.join(*os.path.dirname(os.path.abspath(__file__)).split(os.path.sep))==os.path.dirname(os.path.abspath(__file__))

But it is False on windows machines.




回答7:


to join a windows path, try

mypath=os.path.join('c:\\', 'sourcedir')

basically, you will need to escape the slash




回答8:


You have a few possible approaches to treat path on Windows, from the most hardcoded ones (as using raw string literals or escaping backslashes) to the least ones. Here follows a few examples that will work as expected. Use what better fits your needs.

In[1]: from os.path import join, isdir

In[2]: from os import sep

In[3]: isdir(join("c:", "\\", "Users"))
Out[3]: True

In[4]: isdir(join("c:", "/", "Users"))
Out[4]: True

In[5]: isdir(join("c:", sep, "Users"))
Out[5]: True



回答9:


Consent with @georg-

I would say then why we need lame os.path.join- better to use str.join or unicode.join e.g.

sys.path.append('{0}'.join(os.path.dirname(__file__).split(os.path.sep)[0:-1]).format(os.path.sep))


来源:https://stackoverflow.com/questions/2422798/python-os-path-join-on-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!