Sprawdź, czy katalog istnieje i utwórz go, jeśli to konieczne?
Bezpośrednią odpowiedzią na to jest założenie prostej sytuacji, w której nie spodziewasz się, że inni użytkownicy lub procesy będą bałagać się w twoim katalogu:
if not os.path.exists(d):
os.makedirs(d)
lub jeśli utworzenie katalogu podlega warunkom wyścigu (tj. jeśli po sprawdzeniu ścieżki istnieje, coś innego mogło już to zrobić):
import errno
try:
os.makedirs(d)
except OSError as exception:
if exception.errno != errno.EEXIST:
raise
Być może jednak jeszcze lepszym rozwiązaniem jest ominięcie problemu rywalizacji o zasoby za pomocą katalogów tymczasowych poprzez tempfile
:
import tempfile
d = tempfile.mkdtemp()
Oto najważniejsze informacje z dokumentu online:
mkdtemp(suffix='', prefix='tmp', dir=None)
User-callable function to create and return a unique temporary
directory. The return value is the pathname of the directory.
The directory is readable, writable, and searchable only by the
creating user.
Caller is responsible for deleting the directory when done with it.
Nowości w Python 3.5: pathlib.Path
zexist_ok
Jest nowy Path
obiekt (od wersji 3.4) z wieloma metodami, których chcielibyśmy używać ze ścieżkami - jedną z nich jestmkdir
.
(Dla kontekstu śledzę mojego cotygodniowego przedstawiciela za pomocą skryptu. Oto odpowiednie części kodu ze skryptu, które pozwalają mi uniknąć uderzenia przepełnienia stosu więcej niż raz dziennie dla tych samych danych.)
Najpierw odpowiedni przywóz:
from pathlib import Path
import tempfile
Nie musimy się os.path.join
teraz zajmować - po prostu połącz części ścieżki za pomocą /
:
directory = Path(tempfile.gettempdir()) / 'sodata'
Następnie idempotentnie upewniam się, że katalog istnieje - exist_ok
argument pojawia się w Pythonie 3.5:
directory.mkdir(exist_ok=True)
Oto odpowiednia część dokumentacji :
Jeśli exist_ok
jest to prawda, FileExistsError
wyjątki zostaną zignorowane (to samo zachowanie, co POSIX mkdir -p
polecenie), ale tylko wtedy, gdy ostatni element ścieżki nie jest istniejącym plikiem spoza katalogu.
Oto trochę więcej skryptu - w moim przypadku nie podlegam warunkom wyścigowym, mam tylko jeden proces, który oczekuje, że katalog (lub zawarte pliki) tam będzie, i nie mam nic, co próbuje usunąć katalog.
todays_file = directory / str(datetime.datetime.utcnow().date())
if todays_file.exists():
logger.info("todays_file exists: " + str(todays_file))
df = pd.read_json(str(todays_file))
Path
obiekty muszą zostać wymuszone, str
zanim inne interfejsy API oczekujące str
ścieżek będą mogły ich używać.
Może Pandy powinny być aktualizowane, aby zaakceptować wystąpień abstrakcyjnej klasy bazowej os.PathLike
.