I have following code:
directory = r'D:\images'
for file in os.listdir(directory):
print(os.path.abspath(file))
and I want next output:
- D:\images\img1.jpg
- D:\images\img2.jpg and so on
But I get different result:
- D:\code\img1.jpg
- D:\code\img2.jpg
where D:\code is my current working directory and this result is the same as
os.path.normpath(os.path.join(os.getcwd(), file))
So, the question is: What is the purpose of os.path.abspath while I must use
os.path.normpath(os.path.join(directory, file))
to get REAL absolute path of my file? Show real use-cases if possible.
The problem is with your understanding of os.listdir()
not os.path.abspath()
. os.listdir()
returns the names of each of the files in the directory. This will give you:
img1.jpg
img2.jpg
...
When you pass these to os.path.abspath()
, they are seen as relative paths. This means it is relative to the directory from where you are executing your code. This is why you get "D:\code\img1.jpg".
Instead, what you want to do is join the file names with the directory path you are listing.
os.path.abspath(os.path.join(directory, file))
listdir
produces the file names in a directory, with no reference to the name of the directory itself. Without any other information, abspath
can only form an absolute path from the only directory it can know about: the current working directory. You can always change the working directory before your loop:
os.chdir(directory)
for f in os.listdir('.'):
print(os.path.abspath(f))
Python's native os.listdir
and os.path
functions are pretty low-level. Iterating through a directory (or a series of descending directories) requires your program to assemble file paths manually. It can be convenient to define a utility function that generates the paths you're going to need just once, so that path assembly logic doesn't have to be repeated in every directory iteration. For example:
import os
def better_listdir(dirpath):
"""
Generator yielding (filename, filepath) tuples for every
file in the given directory path.
"""
# First clean up dirpath to absolutize relative paths and
# symbolic path names (e.g. `.`, `..`, and `~`)
dirpath = os.path.abspath(os.path.expanduser(dirpath))
# List out (filename, filepath) tuples
for filename in os.listdir(dirpath):
yield (filename, os.path.join(dirpath, filename))
if __name__ == '__main__':
for fname, fpath in better_listdir('~'):
print fname, '->', fpath
Alternatively, there are "higher level" path modules that one can employ, such as py.path, path.py, and pathlib (now a standard part of Python, for version 3.4 and above, but available for 2.7 forward). Those add dependencies to your project, but up-level many aspects of file, filename, and filepath handling.
来源:https://stackoverflow.com/questions/24705679/misunderstanding-of-python-os-path-abspath