web-dev-qa-db-ja.com

python os.path.abspathの誤解

私は次のコードを持っています:

directory = r'D:\images'
for file in os.listdir(directory):
    print(os.path.abspath(file))

次の出力が必要です:

  • D:\ images\img1.jpg
  • D:\ images\img2.jpgなど

しかし、私は異なる結果を得る:

  • D:\ code\img1.jpg
  • D:\ code\img2.jpg

ここで、D:\ codeは現在の作業ディレクトリであり、この結果は次と同じです

os.path.normpath(os.path.join(os.getcwd(), file))

だから、質問は次のとおりです:os.path.abspathの目的は何ですか?

os.path.normpath(os.path.join(directory, file))

ファイルの実際の絶対パスを取得するには?可能であれば、実際のユースケースを表示します。

22
Most Wanted

問題は、os.listdir()ではなくos.path.abspath()を理解していることです。 os.listdir()は、ディレクトリ内の各ファイルの名前を返します。これにより、以下が得られます。

_img1.jpg
img2.jpg
...
_

これらをos.path.abspath()に渡すと、それらは相対パスと見なされます。これは、コードを実行しているディレクトリからの相対であることを意味します。これが「D:\ code\img1.jpg」を取得する理由です。

代わりに、ファイル名をリストしているディレクトリパスと結合します。

_os.path.abspath(os.path.join(directory, file))
_
34
unholysampler

listdirは、ファイル名を生成しますinディレクトリ。ディレクトリ自体の名前への参照はありません。他の情報がなければ、abspathは、知ることができる唯一のディレクトリ(現在の作業ディレクトリ)からの絶対パスのみを形成できます。ループの前にいつでも作業ディレクトリを変更できます。

os.chdir(directory)
for f in os.listdir('.'):
    print(os.path.abspath(f))
5
chepner

Pythonのネイティブos.listdirおよびos.path関数はかなり低レベルです。ディレクトリ(または一連の降順ディレクトリ)を反復するには、プログラムでファイルパスを手動でアセンブルする必要があります。必要なパスを1回だけ生成するユーティリティ関数を定義すると、ディレクトリの繰り返しごとにパスアセンブリロジックを繰り返す必要がないため便利です。例えば:

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

代わりに、 py.pathpath.py 、および pathlib (現在バージョン3.4以降のPythonの標準部分ですが、2.7以降で使用可能です。これらはプロジェクトに依存関係を追加しますが、ファイル、ファイル名、およびファイルパス処理の多くの側面をアップレベルにします。

3
Jonathan Eunice