Если вы запускаете скрипт C:Scriptsscript.py
из D:work
папки:
D:work> py C:Scriptsscript.py
то:
D:work
— это текущая рабочая директория на момент старта скрипта.open('file.txt')
будет пытаться открытьD:workfile.txt
файлC:Scripts
— это директория со скриптом.
Текущая рабочая директория
Текущая рабочая директория возвращается os.getcwd()
функцией, где CWD
это Current Working Directory («текущая рабочая директория»). os.getcwdb()
возвращает путь в виде байт. Происхождение функции от POSIX getcwd(3)
. Другие способы могут вернуть разные результаты в зависимости от настроек доступа промежуточных директорий, общей длины (от платформы зависит) итд—не изобретайте своих способов, если не осознаёте всех последствий возможного изменения в поведении функции. Также нетрадиционные способы получения рабочей директории могут ухудшить читаемость другими Питон-программистами. Из The Zen of Python
:
There should be one— and preferably only one —obvious way to do it.
По умолчанию относительные пути используют именно эту директорию, поэтому явно вызывать os.getcwd()
редко нужно. Например, open('file.txt')
вызов открывает файл 'file.txt'
в текущей директории. Если необходимо передать полный путь в виде строки, то можно использовать os.path.abspath('file.txt')
—getcwd()
снова явно не используется.
Path.cwd()
из pathlib
модуля возвращает путь к текущей директории как объект c разными полезными и удобными методами такими как .glob('**/*.py')
.
Директория со скриптом
Текущая рабочая директория может отличаться от директории с текущим Питон-скриптом. Часто, но не всегда можно os.path.dirname(os.path.abspath(__file__))
использовать, чтобы получить директорию с текущим Питон скриптом, но это не всегда работает. Посмотрите на get_script_dir()
функцию, которая поддерживает более общий случай.
Если хочется получить данные из файла, расположенного относительно установленного Питон-модуля, то используйте pkgutil.get_data()
или setuptools’ pkg_resources.resource_string()
вместо построения путей c помощью __file__
. Это работает даже, если ваш пакет упакован в архив. В Python 3.7 появился importlib.resources
модуль. К примеру, если у вас есть Питон пакет data
внутри которого лежит файл.txt
, то чтобы достать текст:
import importlib.resources
text = importlib.resources.read_text('data', 'файл.txt')
Если вы хотите найти место куда пользовательские данные можно положить, то appdirs
модуль предоставляет переносимый способ:
import appdirs # $ pip install appdirs
user_data_dir = appdirs.user_data_dir("Название приложения", "Кто создал")
Разные платформы (Windows, MacOS, Linux) используют разные соглашения, appdirs
позволяет не плодить сущностей и использовать на каждой платформе подходящие директории.
The pathlib
module, introduced in Python 3.4 (PEP 428 — The pathlib module — object-oriented filesystem paths), makes the path-related experience much much better.
pwd
/home/skovorodkin/stack
tree
.
└── scripts
├── 1.py
└── 2.py
In order to get the current working directory, use Path.cwd()
:
from pathlib import Path
print(Path.cwd()) # /home/skovorodkin/stack
To get an absolute path to your script file, use the Path.resolve()
method:
print(Path(__file__).resolve()) # /home/skovorodkin/stack/scripts/1.py
And to get the path of a directory where your script is located, access .parent
(it is recommended to call .resolve()
before .parent
):
print(Path(__file__).resolve().parent) # /home/skovorodkin/stack/scripts
Remember that __file__
is not reliable in some situations: How do I get the path of the current executed file in Python?.
Please note, that Path.cwd()
, Path.resolve()
and other Path
methods return path objects (PosixPath
in my case), not strings. In Python 3.4 and 3.5 that caused some pain, because open
built-in function could only work with string or bytes objects, and did not support Path
objects, so you had to convert Path
objects to strings or use the Path.open()
method, but the latter option required you to change old code:
File scripts/2.py
from pathlib import Path
p = Path(__file__).resolve()
with p.open() as f: pass
with open(str(p)) as f: pass
with open(p) as f: pass
print('OK')
Output
python3.5 scripts/2.py
Traceback (most recent call last):
File "scripts/2.py", line 11, in <module>
with open(p) as f:
TypeError: invalid file: PosixPath('/home/skovorodkin/stack/scripts/2.py')
As you can see, open(p)
does not work with Python 3.5.
PEP 519 — Adding a file system path protocol, implemented in Python 3.6, adds support of PathLike
objects to the open
function, so now you can pass Path
objects to the open
function directly:
python3.6 scripts/2.py
OK
Время на прочтение
10 мин
Количество просмотров 15K
В каждой операционной системе существуют свои правила построения путей к файлам. Например, в Linux для путей используются прямые слэши (“/”), а в Windows — обратные слэши (“”).
Это незначительное отличие может создать проблемы, если вы занимаетесь проектом и хотите, чтобы другие разработчики, работающие в разных операционных системах, могли дополнить ваш код.
К счастью, если вы пишете на Python, то с этой задачей успешно справляется модуль Pathlib. Он обеспечит одинаковую работу ваших путей к файлам в разных операционных системах. Кроме того, он предоставляет функциональные возможности и операции, которые помогут вам сэкономить время при обработке и манипулировании путями.
Необходимые условия
Pathlib по умолчанию поставляется с Python >= 3.4. Однако, если вы используете версию Python ниже 3.4, у вас не будет доступа к этому модулю.
Как работает Pathlib?
Чтобы разобраться, как можно построить базовый путь с помощью Pathlib, давайте создадим новый файл Python example.py
и поместим его в определенный каталог.
Откройте файл и введите следующее:
import pathlib
p = pathlib.Path(__file__)
print(p)
example.py
В данном примере мы импортируем модуль Pathlib. Затем создаем новую переменную p
, чтобы сохранить путь. Здесь мы используем объект Path из Pathlib со встроенной в Python переменной под названием __file__
. Эта переменная служит ссылкой на путь к файлу, в котором мы ее прописываем, а именно, example.py
.
Если мы выведем p
, то получим путь к файлу, в котором сейчас находимся:
/home/rochdikhalid/dev/src/package/example.py
Выше показано, что Pathlib создает путь к этому файлу, помещая этот конкретный скрипт в объект Path. Pathlib содержит множество объектов, таких как PosixPath()
и PurePath()
, о которых мы узнаем больше в следующих разделах.
Pathlib делит пути файловой системы на два разных класса, которые представляют два типа объектов пути: Pure Path и Concrete Path.
Pure path предоставляет утилиты для обработки пути к файлу и манипулирования им без совершения операций записи, в то время как Concrete path позволяет производить обработку пути к файлу и выполнять операции записи.
Другими словами, Concrete path — это подкласс Pure path. Он наследует манипуляции от родительского класса и добавляет операции ввода/вывода, которые выполняют системные вызовы.
Pure path в Python
Pure path управляет путем к файлу на вашей машине, даже если он принадлежит другой операционной системе.
Допустим, вы работаете в Linux и хотите использовать путь к файлу Windows. Здесь объекты класса Pure path помогут вам обеспечить работу пути на вашей машине с некоторыми базовыми операциями, такими как создание дочерних путей или доступ к отдельным частям пути.
Но Pure path не сможет имитировать некоторые другие операции, такие как создание каталога или файла, потому что вы не находитесь в этой операционной системе.
Как использовать Pure path
Как видно из приведенной выше диаграммы, Pure path состоит из трех классов, которые обрабатывают любой путь к файловой системе на вашем компьютере:
PurePath() — это корневой узел, который обеспечивает операции по обработке каждого объекта пути в Pathlib.
Когда вы инстанцируете PurePath()
, он создает два класса для обработки путей Windows и других, отличных от Windows. PurePath()
создает общий объект пути «agnostic path», независимо от операционной системы, в которой вы работаете.
In [*]: pathlib.PurePath('setup.py')
Out[*]: PurePosixPath('setup.py')
PurePath() в приведенном выше примере создает PurePosixPath()
, поскольку мы предположили, что работаем на машине Linux. Но если вы создадите его на Windows, то получите что-то вроде PureWindowsPath('setup.py')
.
PurePosixPath() — это дочерний узел PurePath(), реализованный для путей файловой системы, отличной от Windows.
In [*]: pathlib.PurePosixPath('setup.py')
Out[*]: PurePosixPath('setup.py')
Если вы инстанцируете PurePosixPath()
в Windows, то не возникнет никакой ошибки, просто потому что этот класс не выполняет системных вызовов.
PureWindowsPath() — это дочерний узел PurePath()
, реализованный для путей файловой системы Windows.
In [*]: pathlib.PureWindowsPath('setup.py')
Out[*]: PureWindowsPath('setup.py')
То же самое относится и к PureWindowsPath()
, поскольку этот класс не предусматривает системных вызовов, следовательно, его инстанцирование не вызовет ошибок для других операционных систем.
Свойства Pure path
Каждый подкласс в PurePath()
предоставляет следующие свойства:
PurePath().parent выводит родительский класс:
In [*]: pathlib.PurePath('/src/goo/scripts/main.py').parent
Out[*]: PurePosixPath('/src/goo/scripts')
В примере выше мы используем свойство .parent
, чтобы получить путь к логическому родителю main.py
.
PurePath().parents[] выводит предков пути:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py')
p.parents[0]
Out[*]: PurePosixPath('/src/goo/scripts')
In [*]: p.parents[1]
Out[*]: PurePosixPath('/src/goo')
Вы всегда должны указывать индекс предка в квадратных скобках, как показано выше. В Python 3.10 и выше можно использовать срезы и отрицательные значения индекса.
PurePath().name предоставляет имя последнего компонента вашего пути:
In [*]: pathlib.PurePath('/src/goo/scripts/main.py').name
Out[*]: 'main.py'
В этом примере конечным компонентом пути является main.py
. Таким образом, свойство .name
выводит имя файла main.py
, то есть main с суффиксом .py.
В свою очередь, PurePath().suffix предоставляет расширение файла последнего компонента вашего пути:
In [*]: pathlib.PurePath('/src/goo/scripts/main.py').suffix
Out[*]: '.py'
По сравнению со свойством .name
, .suffix
выводит расширение файла и исключает имя файла.
PurePath().stem выводит только имя конечного компонента вашего пути без суффикса:
In [*]: pathlib.PurePath('/src/goo/scripts/main.py').stem
Out[*]: 'main'
Как видно выше, свойство .stem
исключает суффикс конечного компонента main.p
y и предоставляет только имя файла.
Методы Pure path
Каждый подкласс PurePath()
предоставляет следующие методы:
PurePath().is_absolute() проверяет, является ли ваш путь абсолютным или нет:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py')
p.is_absolute()
Out[*]: True
In [*]: o = pathlib.PurePath('scripts/main.py')
o.is_absolute()
Out[*]: False
Обратите внимание, что абсолютный путь состоит из корня и имени диска. В данном случае PurePath()
не позволяет нам узнать имя диска.
Если вы используете PureWindowsPath()
, то можете репрезентовать абсолютный путь, содержащий имя диска, как PureWindowsPath('c:/Program Files')
.
PurePath().is_relative() проверяет, принадлежит ли данный путь другому заданному пути или нет:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py')
p.is_relative_to('/src')
Out[*]: True
In [*]: p.is_relative_to('/data')
Out[*]: False
В данном примере заданный путь /src
является частью или принадлежит пути p
, в то время как другой заданный путь /data
выдает False
, поскольку он не имеет никакого отношения к пути p
.
PurePath().joinpath() конкатенирует путь с заданными аргументами (дочерними путями):
In [*]: p = pathlib.PurePath('/src/goo')
p.joinpath('scripts', 'main.py')
Out[*]: PurePosixPath('/src/goo/scripts/main.py')
Обратите внимание, что нет необходимости добавлять слэши в заданные аргументы, так как метод .joinpath()
делает это за вас.
PurePath().match() проверяет, соответствует ли путь заданному шаблону:
In [*]: pathlib.PurePath('/src/goo/scripts/main.py').match('*.py')
Out[*]: True
In [*]: pathlib.PurePath('/src/goo/scripts/main.py').match('goo/*.py')
Out[*]: True
In [*]: pathlib.PurePath('src/goo/scripts/main.py').match('/*.py')
Out[*]: False
Исходя из приведенных примеров, шаблон должен совпадать с путем. Если заданный шаблон является абсолютным, то и путь должен быть абсолютным.
PurePath().with_name() изменяет имя конечного компонента вместе с его суффиксом:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py')
p.with_name('app.js')
Out[*]: PurePosixPath('/src/goo/scripts/app.js')
In [*]: p
Out[*]: PurePosixPath('/src/goo/scripts/main.py')
Метод .with_name()
не изменяет имя последнего компонента навсегда. Кроме того, если указанный путь не содержит имени, возникает ошибка, как отмечено в официальной документации.
PurePath().with_stem() изменяет только имя последнего компонента пути:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py')
p.with_stem('app.py')
Out[*]: PurePosixPath('/src/goo/scripts/app.py')
In [*]: p
Out[*]: PurePosixPath('/src/goo/scripts/main.py')
Это аналогично методу .with_name()
. Метод .with_stem()
изменяет имя последнего компонента на время. Также, если указанный путь не содержит имени, произойдет ошибка.
PurePath().with_suffix() временно изменяет суффикс или расширение последнего компонента пути:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py')
p.with_suffix('.js')
Out[*]: PurePosixPath('/src/goo/scripts/main.js')
Если имя заданного пути не содержит суффикса, метод .with_suffix()
добавляет суффикс за вас:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main')
p.with_suffix('.py')
Out[*]: PurePosixPath('/src/goo/scripts/main.py')
Но если мы не включим суффикс и оставим аргумент пустым ' '
, текущий суффикс будет удален.
In [*]: p = pathlib.PurePath('/src/goo/scripts/main')
p.with_suffix('')
Out[*]: PurePosixPath('/src/goo/scripts/main')
Некоторые методы, такие как .with_stem()
и .is_relative_to()
, были недавно добавлены в Python 3.9 и выше. Поэтому, если вы их вызываете, используя Python 3.8 или ниже, будет выдана ошибка атрибута.
Concrete Path в Python
Concrete Paths позволяет обрабатывать, манипулировать и выполнять операции записи над различными путями файловой системы.
Другими словами, этот тип объекта пути помогает нам создать, скажем, новый файл, новый каталог и выполнить другие операции ввода/вывода, не находясь в данной операционной системе.
Как использовать Concrete path
В Concrete path обрабатываются любые пути файловой системы и выполняются системные вызовы на вашем компьютере. Эти объекты пути являются дочерними путями Pure path и состоят из трех подклассов, как и сами Pure path:
Path() — это дочерний узел PurePath()
, он обеспечивает операции обработки с возможностью выполнения процесса записи.
Когда вы инстанцируете Path()
, он создает два класса для работы с путями Windows и отличных от Windows. Как и PurePath()
, Path()
также создает общий объект пути «agnostic path», независимо от операционной системы, в которой вы работаете.
In [*]: pathlib.Path('setup.py')
Out[*]: PosixPath('setup.py')
Path()
в приведенном выше примере создает PosixPath()
, поскольку мы предполагаем, что работаем на Linux. Но если вы создадите его в Windows, то получите что-то вроде WindowsPath('setup.py')
.
PosixPath() — это дочерний узел Path()
и PurePosixPath()
, реализованный для обработки и управления путями файловой системы, отличной от Windows.
In [*]: pathlib.PosixPath('setup.py')
Out[*]: PosixPath('setup.py')
Вы получите ошибку при инстанцировании PosixPath()
на компьютере с Windows, поскольку нельзя выполнять системные вызовы во время работы в другой операционной системе.
WindowsPath() — это дочерний узел Path()
и PureWindowsPath()
, реализованный для путей файловой системы Windows.
In [*]: pathlib.WindowsPath('setup.py')
Out[*]: WindowsPath('setup.py')
То же самое относится и к WindowsPath()
, поскольку вы работаете в другой операционной системе — поэтому ее инстанцирование приведет к ошибке.
Свойства Concrete path
Поскольку Concrete path является подклассом Pure path, вы можете делать с Concrete path все, что угодно, используя свойства PurePath()
. Это означает, что мы можем использовать, например, свойство .with_suffix
для добавления суффикса к Concrete path:
In [*]: p = pathlib.Path('/src/goo/scripts/main')
p.with_suffix('.py')
Out[*]: PosixPath('/src/goo/scripts/main.py')
Или вы можете проверить, относится ли данный путь к исходному пути с помощью .is_relative_to
:
In [*]: p = pathlib.Path('/src/goo/scripts/main.py')
p.is_relative_to('/src')
Out[*]: True
Всегда помните, что Concrete path наследуют операции обработки от Pure path и добавляют операции записи, которые выполняют системные вызовы и конфигурации ввода/вывода.
Методы Concrete path
Каждый подкласс Path()
предоставляет следующие методы для обработки путей и выполнения системных вызовов:
Path().iterdir() возвращает содержимое каталога. Допустим, у нас есть следующая папка, содержащая следующие файлы:
data
population.json
density.json
temperature.yml
stats.md
details.txt
папка данных
Чтобы вернуть содержимое каталога /data
, вы можете использовать метод .iterdir()
:
In [*]: p = pathlib.Path('/data')
for child in p.iterdir():
print(child)
Out[*]: PosixPath('/data/population.json')
PosixPath('/data/density.json')
PosixPath('/data/temprature.yml')
PosixPath('/data/stats.md')
PosixPath('/data/details.txt')
Метод .itertir()
создает итератор, который случайным образом перечисляет файлы.
Path().exists() проверяет, существует ли файл/каталог в текущем пути. Давайте воспользуемся каталогом из предыдущего примера (наш текущий каталог — /data
):
In [*]: p = pathlib.Path('density.json').exists()
p
Out[*]: True
Метод .exists() возвращает True
, если заданный файл существует в каталоге data
. Метод возвращает False
, если его нет.
In [*]: p = pathlib.Path('aliens.py').exists()
p
Out[*]: False
То же самое относится и к каталогам, метод возвращает True
, если заданный каталог существует, и False
, если каталог отсутствует.
Path().mkdir() создает новый каталог по заданному пути:
In [*]: p = pathlib.Path('data')
directory = pathlib.Path('data/secrets')
directory.exists()
Out[*]: False
In [*]: directory.mkdir(parents = False, exist_ok = False)
directory.exists()
Out[*]: True
Согласно официальной документации, метод .mkdir()
принимает три аргумента. В данный момент мы сосредоточимся только на аргументах parents
и exist_ok
.
По умолчанию оба аргумента имеют значение False
. Аргумент parents выдает ошибку FileNotFound в случае отсутствия родителя, а exist_ok
выдает ошибку FileExists, если данный каталог уже существует.
В приведенном примере вы можете установить аргументы в True
, чтобы игнорировать упомянутые ошибки и обновить каталог.
Мы также можем создать новый файл по указанному пути с помощью метода Path().touch()
:
In [*]: file = pathlib.Path('data/secrets/secret_one.md')
file.exists()
Out[*]: False
In [*]: file.touch(exist_ok = False)
file.exists()
Out[*]: True
Та же логика применима к методу .touch()
. Здесь параметр exist_ok
может быть установлен в True
, чтобы игнорировать ошибку FileExists и обновить файл.
Path().rename() переименовывает файл/каталог по заданному пути. Рассмотрим пример на примере нашего каталога /data
:
In [*]: p = pathlib.Path('density.json')
n = pathlib.Path('density_2100.json')
p.rename(n)
Out[*]: PosixPath('density_2100.json')
Если вы присваиваете методу несуществующий файл, он выдает ошибку FileNotFound. То же самое относится и к каталогам.
Path().read_text() возвращает содержимое файла в формате строки:
In [*]: p = pathlib.Path('info.txt')
p.read_text()
Out[*]: 'some text added'
Также вы можете использовать метод write_text()
для записи содержимого в файл:
In [*]: p = pathlib.Path('file.txt')
p.write_text('we are building an empire')
Out[*]: 'we are building an empire'
Обратите внимание, что метод .write_text()
был добавлен в Python 3.5 и недавно был обновлен в Python 3.10, получив некоторые дополнительные параметры.
Важное замечание
Вы можете спросить себя, зачем использовать пути файловой системы Windows — ведь каждый пакет должен быть совместим и с другими операционными системами, а не только с Windows.
Вы правы, если цель состоит в том, чтобы сделать путь, не зависящий от ОС. Но иногда мы не можем этого сделать из-за некоторых параметров, уникальных для Windows или Posix систем. Вот почему предоставляются данные объекты — чтобы помочь разработчикам справиться с такими вариантами использования.
Некоторые пакеты нацелены на решение проблем, присутствующих только в экосистеме Windows, и Python поддерживает эти юзкейсы в данной библиотеке.
Что дальше?
Надеемся, это руководство помогло вам узнать, как и зачем использовать Pathlib и в чем его польза для обработки и манипулирования путями файловой системы.
Было бы здорово обыграть полученные знания и воплотить их в реальном проекте.
В этой статье я рассказал об основах, необходимых для использования Pathlib в вашем проекте.
В официальной документации описано больше методов и свойств, которые вы можете применить к путям файловой системы: Pathlib — Объектно-ориентированные пути файловой системы
Всех желающих приглашаем на открытое занятие, на котором научимся работать со встроенными модулями. Узнаем про модули (os, pathlib, functools). Регистрация открыта по ссылке.
In this article, we will cover How to Get and Change the Current Working Directory in Python. While working with file handling you might have noticed that files are referenced only by their names, e.g. ‘GFG.txt’ and if the file is not located in the directory of the script, Python raises an error.
The concept of the Current Working Directory (CWD) becomes important here. Consider the CWD as the folder, the Python is operating inside. Whenever the files are called only by their name, Python assumes that it starts in the CWD which means that a name-only reference will be successful only if the file is in the Python’s CWD.
Note: The folder where the Python script is running is known as the Current Directory. This may not be the path where the Python script is located.
What is the Python os module?
Python provides os module for interacting with the operating system. This module comes under Python’s standard utility module. All functions in the os module raise OSError in the case of invalid or inaccessible file names and paths, or other arguments that have the correct type but are not accepted by the operating system.
Using os.getcwd() method to get Python Script location
The os.getcwd() method is used for getting the Current Working Directory in Python. The absolute path to the current working directory is returned in a string by this function of the Python OS module.
Syntax of os.getcwd() method
Syntax: os.getcwd()
Parameter: No parameter is required.
Return Value: This method returns a string which represents the current working directory.
Example 1: Get the current working directory using os.getcwd()
I have placed the Python file (test.py) inside /home/tuhingfg/Documents/Scripts/test.py. And running the Python Script from the Scripts folder.
Python3
import
os
print
(
"File location using os.getcwd():"
, os.getcwd())
Output:
File location using os.getcwd(): /home/tuhingfg/Documents/Scripts
Note: Using os.getcwd() doesn’t work as expected when running the Python code from different directory as the Python script.
Example 2: Unexpected result when running Python script from different directory other than script using os.getcwd()
Python3
import
os
print
(
"File location using os.getcwd():"
, os.getcwd())
Output:
Get Script location using os.getcwd()
Explanation: The Python script is placed inside /home/tuhingfg/Documents/Scripts. When we run the script from inside the same folder, it gives correct script location. But when we change our directory to some other place, it outputs the location of that directory. This is because, os.getcwd() considers the directory from where we are executing the script. Based on this, the result of os.getcwd() also varies.
Using os.path.realpath() method to get Python Script location
os.path.realpath() can be used to get the path of the current Python script. Actually, os.path.realpath() method in Python is used to get the canonical path of the specified filename by eliminating any symbolic links encountered in the path. A special variable __file__ is passed to the realpath() method to get the path of the Python script.
Note: __file__ is the pathname of the file from which the module was loaded if it was loaded from a file.
Syntax of os.path.realpath() method
Syntax: os.path.realpath(path)
Parameter:
- path: A path-like object representing the file system path. A path-like object is either a string or bytes object representing a path.
Return Type: This method returns a string value which represents the canonical path.
Example: Get the directory script path using __file__ special variable
Inside a Python script, we can use os.path.realpath() and __file__ special variable to get the location of the script. And the result obtained from this method doesn’t depend on the location of execution of the script.
Python3
import
os
print
(
"File location using os.getcwd():"
, os.getcwd())
print
(f
"File location using __file__ variable: {os.path.realpath(os.path.dirname(__file__))}"
)
Output:
Explanation: Here, the os.getcwd() and __file__ provides two different results. Since, we are executing the script from a different folder than the script, os.getcwd() output has changed according to the folder of execution of the script. But __file__ generates the constant result irrespective of the current working directory.
Last Updated :
09 Sep, 2022
Like Article
Save Article
Модуль Python OS используется для работы с операционной системой и является достаточно большим, что бы более конкретно описать его применение. С помощью его мы можем получать переменные окружения PATH, названия операционных систем, менять права на файлах и многое другое. В этой статье речь пойдет про работу с папками и путями, их создание, получение списка файлов и проверка на существование. Примеры приведены с Python 3, но и с предыдущими версиями ошибок быть не должно.
Модуль OS не нуждается в дополнительной установке, так как поставляется вместе с инсталлятором Python.
Получение директорий и списка файлов
Есть несколько способов вернуть список каталогов и файлов по указанному пути. Первый способ используя os.walk, который возвращает генератор:
import os
path = 'C:/windows/system32/drivers/'
print(path)
Такие объекты можно итерировать для понятного отображения структуры:
import os
path = 'C:/Folder1'
for el in os.walk(path):
print(el)
Сам кортеж делится на 3 объекта: текущая директория, имя вложенных папок (если есть), список файлов. Я так же разделил их на примере ниже:
import os
path = 'C:/Folder1'
for dirs,folder,files in os.walk(path):
print('Выбранный каталог: ', dirs)
print('Вложенные папки: ', folder)
print('Файлы в папке: ', files)
print('n')
Os.walk является рекурсивным методом. Это значит, что для поиска файлов в конкретной директории вы будете итерировать и все вложенные папки. Обойти это с помощью самого метода нельзя, но вы можете использовать break так как os.walk возвращает указанную директорию первой. Можно так же использовать next():
import os
path = 'C:/Folder1'
for dirs,folder,files in os.walk(path):
print('Выбранный каталог: ', dirs)
print('Вложенные папки: ', folder)
print('Файлы в папке: ', files)
print('n')
# Отобразит только корневую папку и остановит цикл
break
# Отобразит первый итерируемый объект
directory = os.walk(path)
print(next(directory))
Получение файлов через listdir
Есть еще один метод получения файлов используя listdir. Отличия от предыдущего метода в том, что у нас не будет разделения файлов и папок. Он так же не является рекурсивным:
import os
path = 'C:/Folder1'
directory = os.listdir(path)
print(directory)
Получение полного абсолютного пути к файлам
Для последующего чтения файла нам может понадобится абсолютный путь. Мы можем использовать обычный метод сложения строк или метод os.path.join, который сделает то же самое, но и снизит вероятность ошибки если программа работает на разных ОС:
import os
path = 'C:/Folder1'
for dirs,folder,files in os.walk(path):
print('Выбранный каталог: ', dirs)
print('Вложенные папки: ', folder)
print('Файлы в папке: ', files)
print('Полный путь к файлу: ', os.path.join(dirs, files))
Исключение каталогов или файлов из списка
У нас может быть список полных путей, например из списка выше, из которого мы хотим исключить папки или файлы. Для этого используется os.path.isfile:
import os
path = ['C:/Folder1',
'C:/Folder1/Folder2/file2.txt']
for el in path:
if os.path.isfile(el):
print('Это файл: ', el)
else:
print('Это папка: ', el)
Такой же принцип имеют следующие методы:
- os.path.isdir() — относится ли путь к папке;
- os.path.islink() — относится ли путь к ссылке;
Получение расширения файлов
Расширение файла можно получить с помощью os.path.splittext(). Этот метод вернет путь до расширения и само расширение. Этот метод исключает ситуацию, когда точка может стоять в самом пути. Если в качестве пути мы выберем каталог (который не имеет расширения) , результатом будет пустая строка:
import os
path = ['C:/Folder1',
'C:/Folder1/Folder2/file2.txt']
for el in path:
print(os.path.splitext(el))
os.path.basename(path) — вернет имя файла и расширение.
Создание и удаление директорий
Методы по изменению папок следующие:
- os.mkdir() — создаст папку;
- os.rename() — переименует;
- os.rmdir() — удалит.
import os
# Имя новой папки
path = 'C:/Folder1/NewFolder'
# Ее создание
os.mkdir(path)
# Переименуем папку
os.rename(path, 'C:/Folder1/NewFolder2')
# Удалим
os.rmdir('C:/Folder1/NewFolder2')
Если попытаться создать несколько вложенных папок сразу, используя предыдущий пример, появится ошибка FileNotFoundError. Создание папок включая промежуточные выполняется с os.makedirs():
import os
path = 'C:/Folder1/Folder1/Folder1/'
os.makedirs(path)
Проверка директорий и файлов на существование
Если мы пытаемся создать папку с существующим именем, то получим ошибку FileExistsError. Один из способов этого избежать — использование os.path.exists(), который вернет True в случае существования файла или папки:
import os
path = ['C:/Folder1/file1.txt',
'C:/Folder1/NotExistFolder']
for el in path:
if os.path.exists(el):
print('Такой путь существует: ', el)
else:
print('Такого пути нет', el)
Получение и изменение текущей директории
Запуская любую программу или консоль, например CMD, мы это делаем из определенной директории. С этой и соседней директорией мы можем работать без указания полного пути. Для того что бы узнать такую директорию в Python используется метод os.getcwd():
import os
current_dir = os.getcwd()
print(current_dir)
В директории ‘D:’ сохранен мой файл, с которого я запускаю методы. Вы можете изменить такую директорию с os.chdir() . Такой подход удобен, когда файлы, с которыми вы работаете в основном находятся в другом месте и вы сможете избежать написания полного пути:
import os
current_dir = os.getcwd()
print(current_dir)
new_dir = os.chdir('D:/newfolder/')
print(os.getcwd())
Так же как и в любых языках, в любых методах описанных выше, вы можете использовать ‘..’ для работы с директорией выше или ‘/’ для работы со внутренней:
import os
# Текущая директория
print(os.getcwd())
# Переход во внутреннюю
old_dir = os.chdir('/newfolder/')
print(os.getcwd())
# Переход на уровень выше
new_dir = os.chdir('..')
print(os.getcwd())
…
Теги:
#python
#os