web-dev-qa-db-ja.com

Python 2.7で不足している `exist_ok`を回避する方法は?

Python 2.7 os.makedirs()に_exist_ok_がありません。これはPython 3でのみ使用できます。

私はこれが回避策であることを知っています:

_try:
    os.makedirs(settings.STATIC_ROOT)
except OSError as e:
    if e.errno != errno.EEXIST:
        raise
_

カスタムのmy_make_dirs()メソッドを作成して、os.makedirs()の代わりにこれを使用することもできますが、これはいいことではありません。

Python 2.7をサポートすることを強制された場合、最もPythonicな回避策は何ですか?

AFAIK python-future または six はここでは役に立ちません。

19
guettli

それを回避する1つの方法は pathlib を使用することです。 Python 2 のバックポート)があり、そのmkdir()関数はexist_okをサポートしています。

try:
  from pathlib import Path
except ImportError:
  from pathlib2 import Path  # python 2 backport

Path(settings.STATIC_ROOT).mkdir(exist_ok=True)
14
kichik

パスが存在しないことを確認した後、makedirs()を呼び出すことができます。

import os

if not os.path.exists(path):
    os.makedirs(path)
9
Pat Myron
def makedirs(name, exist_ok=False):
    if not os.path.exists(name) or not exist_ok:
        os.makedirs(name)
0
crizCraig

あなたがやっていることはおそらく問題ありませんが、検出して適応したい場合は、実行時にサルパッチを適用できます。これが最良のアイデアだとは言いませんが、奇妙な結果をもたらす可能性がありますが、状況によってはそれで問題ないかもしれません。少なくとも、このコードの前後にいくつかのドキュメントを置いて、次の人またはギャルが何が起こっているかを知るようにします。

これの例は次のとおりです。このスクリプトを引数として「true」またはその他の何かを指定して実行し、違いを確認できます。

Sys.version_infoを使用してpythonのバージョンを検出します: https://docs.python.org/2/library/sys.html#sys.version_info - https://docs.python.org/3/library/sys.html#sys.version_info

import sys
import os


def blah(a):
    return "lskdflsdkfj"


if sys.argv[1] == "true":
    os.listdir = blah

print(os.listdir('.'))
0
jimf

os.makedirs()は再帰的にサブフォルダーを作成し、Path.mkdir()のようなos.mkdir()は既存の場所に新しいディレクトリを作成することしかできないため、受け入れられた回答は不完全です。別のアプローチは、Python2/3間の動作を区別して許容するためにスローされた例外を利用することです。

import errno
import os
import os.path

def makedirs(folder, *args, **kwargs):
  try:
    return os.makedirs(folder, exist_ok=True, *args, **kwargs)
  except TypeError: 
    # Unexpected arguments encountered 
    pass

  try:
    # Should work is TypeError was caused by exist_ok, eg., Py2
    return os.makedirs(folder, *args, **kwargs)
  except OSError as e:
    if e.errno != errno.EEXIST:
      raise

    if os.path.isfile(folder):
      # folder is a file, raise OSError just like os.makedirs() in Py3
      raise

以下も参照してください: ディレクトリ作成時のPython "FileExists"エラー

0
clifflu