3

この問題は簡単に解決できるはずですが、まだ解決できていません。

それぞれが相対または絶対ファイル パスの 2 つのパラメーターを取り、2 番目のパス (開始) に対して解決された最初のパス (ターゲット) であるファイル パスを返す関数が必要です。解決されたパスは、現在のディレクトリからの相対パスまたは絶対パスの場合があります (気にしません)。

ここでは、実装の試みとして、いくつかのドキュメント テストを完了し、いくつかのサンプル ユース ケースを実行します (そして、どこで失敗するかを示します)。実行可能なスクリプトもソース コード リポジトリで入手できますが、変更される可能性があります。実行可能なスクリプトは、パラメーターが指定されていない場合は doctest を実行し、指定されている場合は 1 つまたは 2 つのパラメーターを findpath に渡します。

def findpath(target, start=os.path.curdir):
    r"""
    Find a path from start to target where target is relative to start.

    >>> orig_wd = os.getcwd()
    >>> os.chdir('c:\\windows') # so we know what the working directory is

    >>> findpath('d:\\')
    'd:\\'

    >>> findpath('d:\\', 'c:\\windows')
    'd:\\'

    >>> findpath('\\bar', 'd:\\')
    'd:\\bar'

    >>> findpath('\\bar', 'd:\\foo') # fails with '\\bar'
    'd:\\bar'

    >>> findpath('bar', 'd:\\foo')
    'd:\\foo\\bar'

    >>> findpath('bar\\baz', 'd:\\foo')
    'd:\\foo\\bar\\baz'

    >>> findpath('\\baz', 'd:\\foo\\bar') # fails with '\\baz'
    'd:\\baz'

    Since we're on the C drive, findpath may be allowed to return
    relative paths for targets on the same drive. I use abspath to
    confirm that the ultimate target is what we expect.
    >>> os.path.abspath(findpath('\\bar'))
    'c:\\bar'

    >>> os.path.abspath(findpath('bar'))
    'c:\\windows\\bar'

    >>> findpath('..', 'd:\\foo\\bar')
    'd:\\foo'

    >>> findpath('..\\bar', 'd:\\foo')
    'd:\\bar'

    The parent of the root directory is the root directory.
    >>> findpath('..', 'd:\\')
    'd:\\'

    restore the original working directory
    >>> os.chdir(orig_wd)
    """
    return os.path.normpath(os.path.join(start, target))

doctest のコメントからわかるように、開始でドライブ文字が指定され、ターゲットがドライブのルートに関連している場合、この実装は失敗します。

これにより、いくつかの疑問が生じます

  1. この動作は os.path.join の制限ですか? つまり、os.path.join('d:\foo', '\bar') は 'd:\bar' に解決されますか? Windows ユーザーとして、私はそう考える傾向がありますが、path.join のような成熟した関数をこのユース ケースを処理するために変更する必要があるとは考えたくありません。
  2. これらすべてのテスト ケースで機能する findpath などの既存のターゲット パス リゾルバーの例はありますか?
  3. 上記の質問に「いいえ」の場合、この望ましい動作をどのように実装しますか?
4

1 に答える 1

3

私はあなたに同意します:これはos.path.joinの欠陥のようです。ドライブを個別に処理する必要があるようです。このコードはすべてのテストに合格します。

def findpath(target, start=os.path.curdir):
    sdrive, start = os.path.splitdrive(start)
    tdrive, target = os.path.splitdrive(target)
    rdrive = tdrive or sdrive
    return os.path.normpath(os.path.join(rdrive, os.path.join(start, target)))

(はい、動作させるには2つのos.path.joinをネストする必要がありました...)

于 2009-10-31T15:50:39.840 に答える