I'm trying to do this:
import os
[x for x in os.listdir('.') if os.path.isfile(x)]
[x for x in os.listdir('dirname') if os.path.isfile(x)]
[x for x in os.listdir(os.path.abspath('dirname')) if os.path.isfile(os.path.abspath(x))]
The first line works:
[x for x in os.listdir('.') if os.path.isfile(x)]
But the next two:
[x for x in os.listdir('dirname') if os.path.isfile(x)]
and
[x for x in os.listdir(os.path.abspath('dirname')) if os.path.isfile(os.path.abspath(x))]
just output []
Why?
Because you need to join the dirname
with x
, os.listdir()
just lists the contents directly, the contents do not have full path.
Example -
[x for x in os.listdir('dirname') if os.path.isfile(os.path.join('dirname',x))]
When the full path is not given, os.path.isfile()
searches in the current directory, hence when you give '.'
to os.listdir()
you get a correct list back.
Example -
Lets say some folder - /a/b/c
- has files - x
and y
in it.
when you do - os.listdir('/a/b/c')
, the list returned looks like -
['x','y']
Even if you give absolute path inside os.listdir()
, the files returned in the list would have relative path to the dir. You would manually need to join dir and x
to get the correct results.
In your third example, it does not work because os.path.abspath()
also works with current directory, so if you do something like -
os.path.abspath('somefile')
The result produced would be - /path/to/current/directory/somefile
- it does not validate if that is a real file/dir or not.
It is clearly stated in the documentation (Emphasis mine) -
os.path.abspath(path)
Return a normalized absolutized version of the pathname path. On most platforms, this is equivalent to calling the function normpath() as follows:
normpath(join(os.getcwd(), path))
.
where os.getcwd()
returns the path to current working directory.
isfile()
is looking in the current directory. Unless you include the directory name with the file name it has no idea where to find your files.
来源:https://stackoverflow.com/questions/32157127/os-path-isfile-doesnt-work-why