Is there a universal approach in Python, to find out the path to the file that is currently executing?
Failing approaches
path = os.path.abspath(os.path.dirname(sys.argv[0]))
This does not work if you are running from another Python script in another directory, for example by using execfile
in 2.x.
path = os.path.abspath(os.path.dirname(__file__))
I found that this doesn’t work in the following cases:
py2exe
doesn’t have a__file__
attribute, although there is a workaround- When the code is run from IDLE using
execute()
, in which case there is no__file__
attribute - On Mac OS X v10.6 (Snow Leopard), I get
NameError: global name '__file__' is not defined
Test case
Directory tree
C:.
| a.py
---subdir
b.py
Content of a.py
#! /usr/bin/env python
import os, sys
print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print
execfile("subdir/b.py")
Content of subdir/b.py
#! /usr/bin/env python
import os, sys
print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print
Output of python a.py
(on Windows)
a.py: __file__= a.py
a.py: os.getcwd()= C:zzz
b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:zzz
Related (but these answers are incomplete)
- Find path to currently running file
- Path to current file depends on how I execute the program
- How can I know the path of the running script in Python?
- Change directory to the directory of a Python script
Karl Knechtel
61.6k11 gold badges97 silver badges147 bronze badges
asked Apr 13, 2010 at 18:37
1
First, you need to import from inspect
and os
from inspect import getsourcefile
from os.path import abspath
Next, wherever you want to find the source file from you just use
abspath(getsourcefile(lambda:0))
answered Aug 28, 2013 at 13:19
ArtOfWarfareArtOfWarfare
20.3k19 gold badges131 silver badges192 bronze badges
8
You can’t directly determine the location of the main script being executed. After all, sometimes the script didn’t come from a file at all. For example, it could come from the interactive interpreter or dynamically generated code stored only in memory.
However, you can reliably determine the location of a module, since modules are always loaded from a file. If you create a module with the following code and put it in the same directory as your main script, then the main script can import the module and use that to locate itself.
some_path/module_locator.py:
def we_are_frozen():
# All of the modules are built-in to the interpreter, e.g., by py2exe
return hasattr(sys, "frozen")
def module_path():
encoding = sys.getfilesystemencoding()
if we_are_frozen():
return os.path.dirname(unicode(sys.executable, encoding))
return os.path.dirname(unicode(__file__, encoding))
some_path/main.py:
import module_locator
my_path = module_locator.module_path()
If you have several main scripts in different directories, you may need more than one copy of module_locator.
Of course, if your main script is loaded by some other tool that doesn’t let you import modules that are co-located with your script, then you’re out of luck. In cases like that, the information you’re after simply doesn’t exist anywhere in your program. Your best bet would be to file a bug with the authors of the tool.
answered Apr 13, 2010 at 18:48
Daniel StutzbachDaniel Stutzbach
73.6k17 gold badges88 silver badges77 bronze badges
14
This solution is robust even in executables:
import inspect, os.path
filename = inspect.getframeinfo(inspect.currentframe()).filename
path = os.path.dirname(os.path.abspath(filename))
answered Jun 16, 2017 at 14:54
6
I was running into a similar problem, and I think this might solve the problem:
def module_path(local_function):
''' returns the module path without the use of __file__. Requires a function defined
locally in the module.
from http://stackoverflow.com/questions/729583/getting-file-path-of-imported-module'''
return os.path.abspath(inspect.getsourcefile(local_function))
It works for regular scripts and in IDLE. All I can say is try it out for others!
My typical usage:
from toolbox import module_path
def main():
pass # Do stuff
global __modpath__
__modpath__ = module_path(main)
Now I use _modpath_ instead of _file_.
answered Apr 21, 2011 at 19:04
Garrett BergGarrett Berg
2,5831 gold badge22 silver badges20 bronze badges
7
You have simply called:
path = os.path.abspath(os.path.dirname(sys.argv[0]))
instead of:
path = os.path.dirname(os.path.abspath(sys.argv[0]))
abspath()
gives you the absolute path of sys.argv[0]
(the filename your code is in) and dirname()
returns the directory path without the filename.
answered Apr 4, 2018 at 15:19
dgbdgb
1231 silver badge4 bronze badges
1
The short answer is that there is no guaranteed way to get the information you want, however there are heuristics that work almost always in practice. You might look at How do I find the location of the executable in C?. It discusses the problem from a C point of view, but the proposed solutions are easily transcribed into Python.
answered Apr 16, 2010 at 10:28
Dale HagglundDale Hagglund
16k4 gold badges30 silver badges37 bronze badges
2
See my answer to the question Importing modules from parent folder for related information, including why my answer doesn’t use the unreliable __file__
variable. This simple solution should be cross-compatible with different operating systems as the modules os
and inspect
come as part of Python.
First, you need to import parts of the inspect and os modules.
from inspect import getsourcefile
from os.path import abspath
Next, use the following line anywhere else it’s needed in your Python code:
abspath(getsourcefile(lambda:0))
How it works:
From the built-in module os
(description below), the abspath
tool is imported.
OS routines for Mac, NT, or Posix depending on what system we’re on.
Then getsourcefile
(description below) is imported from the built-in module inspect
.
Get useful information from live Python objects.
abspath(path)
returns the absolute/full version of a file pathgetsourcefile(lambda:0)
somehow gets the internal source file of the lambda function object, so returns'<pyshell#nn>'
in the Python shell or returns the file path of the Python code currently being executed.
Using abspath
on the result of getsourcefile(lambda:0)
should make sure that the file path generated is the full file path of the Python file.
This explained solution was originally based on code from the answer at How do I get the path of the current executed file in Python?.
answered Nov 4, 2015 at 20:42
EdwardEdward
1,0541 gold badge17 silver badges39 bronze badges
2
This should do the trick in a cross-platform way (so long as you’re not using the interpreter or something):
import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))
sys.path[0]
is the directory that your calling script is in (the first place it looks for modules to be used by that script). We can take the name of the file itself off the end of sys.argv[0]
(which is what I did with os.path.basename
). os.path.join
just sticks them together in a cross-platform way. os.path.realpath
just makes sure if we get any symbolic links with different names than the script itself that we still get the real name of the script.
I don’t have a Mac; so, I haven’t tested this on one. Please let me know if it works, as it seems it should. I tested this in Linux (Xubuntu) with Python 3.4. Note that many solutions for this problem don’t work on Macs (since I’ve heard that __file__
is not present on Macs).
Note that if your script is a symbolic link, it will give you the path of the file it links to (and not the path of the symbolic link).
answered Sep 10, 2014 at 21:55
BrōtsyorfuzthrāxBrōtsyorfuzthrāx
4,3173 gold badges33 silver badges56 bronze badges
You can use Path
from the pathlib
module:
from pathlib import Path
# ...
Path(__file__)
You can use call to parent
to go further in the path:
Path(__file__).parent
answered Oct 10, 2016 at 9:49
2
Simply add the following:
from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)
Or:
from sys import *
print(sys.argv[0])
Papershine
4,9352 gold badges23 silver badges45 bronze badges
answered Nov 15, 2017 at 1:35
H. KamranH. Kamran
3662 silver badges12 bronze badges
If the code is coming from a file, you can get its full name
sys._getframe().f_code.co_filename
You can also retrieve the function name as f_code.co_name
answered Oct 25, 2018 at 8:25
Alex CohnAlex Cohn
55.8k9 gold badges111 silver badges303 bronze badges
The main idea is, somebody will run your python code, but you need to get the folder nearest the python file.
My solution is:
import os
print(os.path.dirname(os.path.abspath(__file__)))
With
os.path.dirname(os.path.abspath(__file__))
You can use it with to save photos, output files, …etc
answered Mar 31, 2019 at 15:14
ThienSuBSThienSuBS
1,53417 silver badges26 bronze badges
1
import os
current_file_path=os.path.dirname(os.path.realpath('__file__'))
answered Apr 4, 2019 at 18:25
Mohamed.AbdoMohamed.Abdo
2,0041 gold badge19 silver badges12 bronze badges
2
Given a path such as "mydir/myfile.txt"
, how do I find the file’s absolute path in Python? E.g. on Windows, I might end up with:
"C:/example/cwd/mydir/myfile.txt"
asked Sep 9, 2008 at 10:19
0
>>> import os
>>> os.path.abspath("mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'
Also works if it is already an absolute path:
>>> import os
>>> os.path.abspath("C:/example/cwd/mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'
JakeD
2,6882 gold badges19 silver badges29 bronze badges
answered Sep 9, 2008 at 10:21
sherbangsherbang
15.6k1 gold badge22 silver badges16 bronze badges
8
You could use the new Python 3.4 library pathlib
. (You can also get it for Python 2.6 or 2.7 using pip install pathlib
.) The authors wrote: «The aim of this library is to provide a simple hierarchy of classes to handle filesystem paths and the common operations users do over them.»
To get an absolute path in Windows:
>>> from pathlib import Path
>>> p = Path("pythonw.exe").resolve()
>>> p
WindowsPath('C:/Python27/pythonw.exe')
>>> str(p)
'C:\Python27\pythonw.exe'
Or on UNIX:
>>> from pathlib import Path
>>> p = Path("python3.4").resolve()
>>> p
PosixPath('/opt/python3/bin/python3.4')
>>> str(p)
'/opt/python3/bin/python3.4'
Docs are here: https://docs.python.org/3/library/pathlib.html
answered Oct 24, 2014 at 1:05
twasbrilligtwasbrillig
16.7k9 gold badges43 silver badges66 bronze badges
4
import os
os.path.abspath(os.path.expanduser(os.path.expandvars(PathNameString)))
Note that expanduser
is necessary (on Unix) in case the given expression for the file (or directory) name and location may contain a leading ~/
(the tilde refers to the user’s home directory), and expandvars
takes care of any other environment variables (like $HOME
).
answered Mar 7, 2019 at 0:56
benjiminbenjimin
3,89128 silver badges47 bronze badges
1
Install a third-party path module (found on PyPI
), it wraps all the os.path
functions and other related functions into methods on an object that can be used wherever strings are used:
>>> from path import path
>>> path('mydir/myfile.txt').abspath()
'C:\example\cwd\mydir\myfile.txt'
wim
332k99 gold badges599 silver badges736 bronze badges
answered Sep 12, 2008 at 6:53
TomTom
42.3k33 gold badges94 silver badges101 bronze badges
5
Update for Python 3.4+ pathlib
that actually answers the question:
from pathlib import Path
relative = Path("mydir/myfile.txt")
absolute = relative.absolute() # absolute is a Path object
If you only need a temporary string, keep in mind that you can use Path
objects with all the relevant functions in os.path
, including of course abspath
:
from os.path import abspath
absolute = abspath(relative) # absolute is a str object
answered Dec 27, 2018 at 20:41
Mad PhysicistMad Physicist
106k25 gold badges180 silver badges262 bronze badges
This always gets the right filename of the current script, even when it is called from within another script. It is especially useful when using subprocess
.
import sys,os
filename = sys.argv[0]
from there, you can get the script’s full path with:
>>> os.path.abspath(filename)
'/foo/bar/script.py'
It also makes easier to navigate folders by just appending /..
as many times as you want to go ‘up’ in the directories’ hierarchy.
To get the cwd:
>>> os.path.abspath(filename+"/..")
'/foo/bar'
For the parent path:
>>> os.path.abspath(filename+"/../..")
'/foo'
By combining "/.."
with other filenames, you can access any file in the system.
answered Feb 28, 2019 at 15:26
3
You can use this to get absolute path of a specific file.
from pathlib import Path
fpath = Path('myfile.txt').absolute()
print(fpath)
answered Aug 30, 2021 at 14:44
Dhia ShalabiDhia Shalabi
1,2671 gold badge11 silver badges27 bronze badges
1
Given a path such as
mydir/myfile.txt
, how do I find the file’s absolute path relative to the current working directory in Python?
I would do it like this,
import os.path
os.path.join( os.getcwd(), 'mydir/myfile.txt' )
That returns '/home/ecarroll/mydir/myfile.txt'
answered Feb 8, 2022 at 6:20
Evan CarrollEvan Carroll
77.2k45 gold badges253 silver badges456 bronze badges
if you are on a mac
import os
upload_folder = os.path.abspath("static/img/users")
this will give you a full path:
print(upload_folder)
will show the following path:
>>>/Users/myUsername/PycharmProjects/OBS/static/img/user
answered Apr 3, 2018 at 21:12
chikwapurochikwapuro
1,3281 gold badge9 silver badges10 bronze badges
1
In case someone is using python and linux and looking for full path to file:
>>> path=os.popen("readlink -f file").read()
>>> print path
abs/path/to/file
answered Jul 4, 2018 at 19:09
BNDBND
60213 silver badges22 bronze badges
Взаимодействие с файловой системой#
Нередко требуется программными средствами взаимодействовать с файловой системой и в стандартной библиотеке python
реализовано много инструментов, значительно упрощающих этот процесс.
Путь к файлу/директории#
Путь (англ. path) — набор символов, показывающий расположение файла или каталога в файловой системе (источник — wikipedia). В программных средах путь необходим, например, для того, чтобы открывать и сохранять файлы. В большинстве случаев в python
путь представляется в виде обычного строкового объекта.
Обычно путь представляет собой последовательность вложенных каталогов, разделенных специальным символом, при этом разделитель каталогов может меняться в зависимости от операционной системы: в OS Windows
используется “”, в
unix-like
системах — “/
”. Кроме того, важно знать, что пути бывают абсолютными и относительными. Абсолютный путь всегда начинается с корневого каталога файловой системы (в OS Windows
— это логический раздел (например, “C:”), в UNIX-like
системах — “/”) и всегда указывает на один и тот же файл (или директорию). Относительный путь, наоборот, не начинается с корневого каталога и указывает расположение относительно текущего рабочего каталога, а значит будет указывать на совершено другой файл, если поменять рабочий каталог.
Итого, например, путь к файлу “hello.py” в домашней директории пользователя “ivan” в зависимости от операционной системы будет выглядеть приблизительно следующим образом:
|
|
|
---|---|---|
Глобальный |
C:Usersivanhello.py |
/home/users/ivan/hello.py |
Относительный |
.hello.py |
./hello.py |
В связи с этим требуется прикладывать дополнительные усилия, чтобы заставить работать один и тот же код на машинах с разными операционными системами. Чтобы все же абстрагироваться от того, как конкретно устроена файловая система на каждой конкретной машине, в python
предусмотренны модули стандартной библиотеки os.path и pathlib.
Проблема с путями в стиле Windows
#
Как было отмечено выше, в Windows
в качестве разделителя используется символ обратного слеша (backslash) “”. Это может привести к небольшой путанице у неопытных программистов. Дело в том, что во многих языка программирования (и в
python
, в том числе) символ “” внутри строк зарезервирован для экранирования, т.е. если внутри строки встречается “
“, то он интерпретируется не буквально как символ обратного слеша, а изменяет смысл следующего за ним символом. Так, например, последовательность "n"
представляет собой один управляющий символ перевода строки.
new_line = "n" print(len(new_line))
Это значит, что если вы попробуете записать Windows
путь не учитывая эту особенность, то высока вероятность получить не тот результат, который вы ожидали. Например, строка "C:Users"
вообще не корректна с точки зрения синтаксиса python
:
users_folder = "C:Users"
Input In [10] users_folder = "C:Users" ^ SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated UXXXXXXXX escape
Это объясняется тем, что последовательность "U"
используется для экранирования unicode
последовательностей, а набор символов "sers"
не является корректным unicode
кодом. Ниже приводится пример корректного unicode
кода.
snake_emoji = "U0001F40D" print(snake_emoji)
В python
предусмотренно как минимум два подхода борьбы с этой проблемой.
Первый из них опирается на удвоение количества символов “”. Дело в том, что в последовательности символов “
\
” — первый обратный слеш экранирует второй, т.е. итоговый результат эквивалентен одному настоящему символу обратного слеша.
users_folder = "C:\Users" print(users_folder) new_line = "\n" print(len(new_line))
Второй способ опирается на использование так называемых сырых (raw) строк: если перед началом литерала строки поставить символ “r
”, то символ обратного слеша теряет свою особую роль внутри неё.
users_folder = r"C:Users" print(users_folder) new_line = r"n" print(len(new_line))
Сам факт того, что при ручном прописывании пути в виде строки приходится проявлять дополнительную бдительность намекает на то, что должен быть более осмысленный способ составлении пути.
/
Соединение элементов пути#
Рассмотрим конкретный пример. Пусть у нас имеется строка folder
, представляющая путь к каталогу, и строка filename
, представляющее имя некоего файла внутри этого каталога.
folder = "directory" filename = "file.txt"
Чтобы открыть этот файл, нам потребуется соединить эти две строки, учитывая разделитель каталогов.
Конечно, можно вспомнить, что путь — строка, а значит их можно конкатенировать. Но, что если кто-то захочет запустить ваш код на машине с другой операционной системой? Гораздо целесообразнее воспользоваться для этих целей специальными средствами. Самый надежный способ — метод os.path.join, который на вход принимает произвольное количество имен файлов и соединяет их тем символом, который используется в качестве разделителя на той конкретной машине, на которой скрипт запущен сейчас.
import os path = os.path.join(folder, filename) print(path)
Альтернативой является модуль pathlib, который позволяет обращаться с путями файловой системы в объектно ориентированном стиле, т.е. путь больше не представляется в виде строки, а в виде специального объекта, который в любой момент может быть приведен к строке конструктором строки str.
Для создания такого объекта обычно используют класс Path, при создании экземпляра которого учитывается операционная система, на которой запущен данный скрипт.
from pathlib import Path folder = Path(folder) print(f"{folder=}, {str(folder)=}")
folder=WindowsPath('directory'), str(folder)='directory'
В ячейке выше создается объект типа Path
из строки folder
и вывод сообщает, что создался объект WindowsPath('directory
. Обратите внимание, что автоматически создался путь OS Windows
, т.к. этот скрипт запускался под управлением этой операционной системы.
Чтобы присоединить имя файла к объекту folder
, можно использовать оператор “/
” вне зависимости от операционной системы.
path = folder / filename print(f"{path=}, {str(path)=}")
path=WindowsPath('directory/file.txt'), str(path)='directory\file.txt'
Обратите внимание на то, что при приведении к строке автоматически получилась строка с разделителем в стиле OS Windows
, т.к. при генерации материалов использовался компьютер под управлением OS Windows
.
Автор курса рекомендует всегда использовать средства модулей os.path или pathlib, даже если вам известно, что ваш скрипт будет запускаться под управлением какой-то конкретной операционной системы, чтобы писать более надежный код и формировать полезные привычки.
Извлечение элементов из пути#
Иногда может стоять обратная задача: дан путь, а из него надо что-то извлечь.
path = r"C:Usersfadeevfolderfile.txt"
Метод os.path.splitdrive разбивает строку на логический раздел и остальное (актуально в основном на OS Windows
).
print(f"{path=}") drive, tail = os.path.splitdrive(path) print(f"{drive=}, {tail=}")
path='C:\Users\fadeev\folder\file.txt' drive='C:', tail='\Users\fadeev\folder\file.txt'
Метод os.path.dirname выделяет из пути родительский каталог.
parent_folder = os.path.dirname(path) print(f"{parent_folder=}")
parent_folder='C:\Users\fadeev\folder'
Метод os.path.basename наоборот извлекает имя файла или папки, на которую данный путь указывает без учета родительского каталога.
filename = os.path.basename(path) print(f"{filename=}")
Метаинформация файла/каталога#
Имея путь, можно запрашивать у операционной системы информацию о том, что находится по этому пути. Важно понимать, что на этом этапе всегда происходит запрос к операционной системе и, если у запустившего программу пользователя не хватает привилегий для выполнения запрошенной операции, то в зависимости от операционной системы вы можете получить разные ответы.
Самый фундаментальный вопрос, который можно задать — существует ли вообще что-нибудь по указанному пути? Метод os.path.exists отвечает как раз на этот вопрос.
print(f"{os.path.exists(path)=}, {os.path.exists('filesystem.ipynb')=}")
os.path.exists(path)=False, os.path.exists('filesystem.ipynb')=True
Методы os.path.isdir и os.path.isfile позволяют определить располагает ли по этому пути каталог или файл соответственно. Оба метода возвращают False
, если по переданному пути ничего не располагается.
print(f"{os.path.isdir(folder)=}, {os.path.isfile('filesystem.ipynb')=}")
os.path.isdir(folder)=True, os.path.isfile('filesystem.ipynb')=True
Также иногда бывает полезно узнать время создания (последнего изменения) или последнего доступа к файлу или каталогу. Для этих целей существуют методы os.path.getatime, os.path.getmtime и os.path.getctime. Размер файла можно узнать методом os.path.getsize.
Содержимое каталога#
В ряде задач может потребоваться узнать содержимое определенного каталога, например, чтобы потом в цикле обработать каждый элемент каталога. В самых простых случаях достаточно метода os.listdir, который возвращает список файлов/каталогов в указанной директории. По умолчанию — текущая директория.
for filename in os.listdir(): print(filename, end=" ")
.ipynb_checkpoints about_12_and_so_on.ipynb about_python.ipynb argparse.ipynb custom_classes.ipynb custom_exceptions.ipynb decorators.ipynb dictionaries.ipynb dynamic_typing.ipynb exceptions.ipynb exercises1.ipynb exercises2.ipynb exercises3.ipynb files.ipynb filesystem.ipynb functions.ipynb garbage_collector.ipynb generators.ipynb if_for_range.ipynb inheritance.ipynb iterators.ipynb json.ipynb jupyter.ipynb LBYL_vs_EAFP.ipynb list_comprehensions.ipynb mutability.ipynb numbers_and_lists.ipynb operators_overloading.ipynb polymorphism.ipynb python_scripts.ipynb scripts_vs_modules.ipynb sequencies.ipynb tmp
Важно помнить, что согласно документации этот метод возвращает список файлов в произвольном порядке, т.е. он ни коим образом не отсортирован. Если требуется отсортировать их по названию, например, в алфавитном порядке, то можно воспользоваться встроенной функцией sorted. Практически во всех остальных случаях лучше выбрать os.scandir, которая не только возвращает содержимое каталога (тоже в произвольном порядке), но и метаинформацию о каждом файле.
Метод glob.glob модуля стандартной библиотеки glob позволяет фильтровать содержимое каталога на основе шаблона. В ячейке ниже демонстрируется, как можно найти все файлы в каталоге, которые начинаются с символа “a
”, а завершаются расширением “.ipynb
”.
import glob for filename in glob.glob("a*.ipynb"): print(filename)
about_12_and_so_on.ipynb about_python.ipynb argparse.ipynb
Создание, копирование, перемещение и удаление файлов и каталогов#
Метод os.mkdir создаёт каталог, но две особенности:
-
если такой каталог уже существует, то бросается исключение;
-
если родительского каталога не существует, то тоже бросается исключение.
Альтернативой является метод os.makedirs имеет опциональный параметр exist_ok
, который позволяет игнорировать ошибку, возникающую при попытке создать уже существующий каталог. Кроме того, если для создания указанного каталога, потребуется создать несколько директорий по пути, то они тоже будут созданы.
Таким образом метод os.mkdir более осторожный, т.к. он точно даст знать, если вы пытаетесь повторно создать директорию, а также если вы где-то ошиблись в пути, а метод os.makedirs более гибкий, позволяющий сократить объем кода, но если вы ошиблись при составлении желаемого пути (например, опечатались в имени одного каталога), то вы не получите никакого сообщения об ошибке и итоговая директория все равно будет создана.
Модуль стандартной библиотеки shutil содержит набор методов, имитирующих методы командной строки, что позволяет копировать файлы (методы shutil.copy, shutil.copy2 и shutil.copyfile), копировать директории с их содержимым (метод shutil.copytree), удалять директории (метод shutil.rmtree) и перемещать файлы или директории (метод shutil.move).
Удалять файлы можно методом os.remove.
Время на прочтение
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). Регистрация открыта по ссылке.
Модуль Pathlib в Python упрощает работу с файлами и папками. Он доступен в Python 3.4 и более поздних версиях. Pathlib сочетает в себе лучшее из модулей файловой системы Python — os, os.path, glob и так далее.
Содержание статьи
- Концепт пути и директории в Python
- Как использовать модуль Pathlib?
- Зачем использовать модуль Pathlib?
- Создание и удаление папок через Pathlib
- Генерация кроссплатформенных путей в Pathlib
- Получение информации о пути в Pathlib
- Альтернатива для модуля glob
- Чтение и запись файлов с использованием Pathlib
В Python большинство скриптов предполагает работу с файловыми системами. Следовательно, неизбежно взаимодействие с названиями файлов и путями. Именно для этого в Python есть модуль Pathlib, который содержит полезные функции для выполнения задач, связанных с файлами. Pathlib предоставляет удобный для чтения и простой способ создания путей, представляя пути файловой системы в виде надлежащих объектов. Модуль позволяет создавать код, который можно переносить между платформами.
В данной статье мы подробно изучим модуль Pathlib с помощью различных примеров.
Концепт пути и директории в Python
Перед началом подробного рассмотрения модуля Pathlib важно разобраться в разнице между главными концептами темы — путем (path) и директорией (directory).
- Путь используется для идентификации файла. Путь предоставляет необязательную последовательность названий директорий, в конце которой значится конечное имя файла, а также его расширение;
- Расширение названия файла предоставляет некоторую информацию о формате/содержимом файла. Модуль Pathlib может работать как с абсолютными, так и с относительными путями;
- Абсолютный путь начинается с корневой директории и определяет полное дерево каталогов;
- Относительный путь, как следует из названия, является путем к файлу относительно другого файла или директории, обычно текущей;
- Директория представляет собой запись пути в файловой системе и включает название файла, время создания, размер, владельца и так далее.
Модуль Pathlib в Python занимается задачами, связанными с путями, такими как создание новых путей из названий файлов и других путей, проверка различных свойств путей, создание файлов и папок по определенным путям.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Для работы с Pathlib в Python требуется импортировать все классы данного модуля, используя следующую команду:
В качестве первого задания давайте извлечем текущую рабочую директорию и домашнюю директорию объектов, используя следующий код:
current_dir = Path.cwd() home_dir = Path.home() print(current_dir) print(home_dir) |
Вместо импорта всех классов можно использовать import pathlib
. В таком случае, задействуя классы внутри модуля, требуется добавлять через pathlib
.
import pathlib current_dir = pathlib.Path.cwd() home_dir = pathlib.Path.home() print(current_dir) print(home_dir) |
Зачем использовать модуль Pathlib?
Если вы некоторое время работали с языком Python, у вас может возникнуть вопрос. Зачем нужен модуль Pathlib, когда уже есть модули os
, os.path
, glob
и прочие? Это хороший вопрос. Давайте попробуем ответить на него, разобрав следующий пример.
Допустим, мы хотим создать файл под названием "output/output.xlsx"
в текущем рабочем каталоге. Следующий код пытается сделать это с помощью модуля os.path
. Также используются функции os.getcwd
и os.path.join
.
import os outpath = os.path.join(os.getcwd(), ‘output’) outpath_file = os.path.join(outpath, ‘out.xlsx’) |
Альтернативный способ:
outpath_file = os.pathjoin(os.path.join(os.getcwd(), ‘output’), «out.xlsx») |
Хотя код работает, он выглядит несколько странно, плохо читается, в нем сложно уловить суть. Представьте, как данный код выглядел бы, если бы мы хотели создать новый файл внутри глубоко расположенной директории.
Данный код можно переписать, используя модуль Pathlib:
from pathlib import Path outpath = Path.cwd() / ‘output’ / ‘output.xlsx’ |
Такой формат проще укладывается в голове. В Pathlib функция
Path.cwd()
используется для получения текущего рабочего каталога, а оператор/
используется вместоos.path.join
для объединения частей пути в составной объект пути.
Шаблон вложенности функций в модуле os.path
заменяется классом Path
модуля Pathlib, что представляет путь через объединение методов и атрибутов. Умная перегрузка оператора /
делает код читабельным и простым в обращении.
Другое преимущество метода, предоставляемого модулем Pathlib, заключается в том, что объект Path
создается вместо строкового представления пути. У этого объекта есть несколько удобных методов, что имеют значительное преимущество перед работой с необработанными строками, которые представляют пути.
Создание и удаление папок через Pathlib
Классический модуль os.path
используется только для манипуляции строками пути. Чтобы что-то сделать с путем, например, создать директорию, нам нужен модуль os
. Модуль os
предоставляет набор функций для работы с файлами и каталогами, например: mkdir
для создания директории, rename
для переименования, а getsize
для получения ее размера.
Давайте напишем некоторые из этих операций с помощью модуля os
, а затем перепишем тот же код с помощью модуля Pathlib.
Пример кода, написанный с использованием модуля os
:
if os.path.isdir(path): os.rmdir(path) |
Если мы используем объекты path
модуля Pathlib для достижения той же функциональности, конечный код будет читабельнее и легче для понимания:
if path.is_dir() path.rmdir() |
В модуле os
сложновато найти утилиты, связанные с путем. Модуль Pathlib решает эту проблему, заменяя утилиты модуля os
методами объектов путя. Давайте попробуем разобраться в этом на примере следующего кода:
outpath = os.path.join(os.getcwd(), ‘output’) outpath_tmp = os.path.join(os.getcwd(), ‘output.tmp’) generate_data(output_tmp) if os.path.getsize(output_tmp): os.rename(outpath_tmp, outpath) else: # Ничего не происходит os.remove(outpath_tmp) |
Здесь функция generate_data()
принимает путь к файлу в качестве параметра и записывает данные в другой путь. Однако, если файл, который передается в качестве параметра, не изменяется, так как в последний раз была выполнена функция generate_data()
, генерируется пустой файл. В этом случае пустой файл заменяется предыдущей версией файла.
Переменная outpath
сохраняет данные, соединяя текущий рабочий каталог с названием файла «output». Мы также создаем временную версию, названную outpath.tmp
. Если размер временной версии не равен нулю, что означает, что это не пустой файл, тогда временная версия переименовывается в outpath
, в противном случае временная версия удаляется, а старая версия сохраняется.
Используя модуль os
, манипулирование путями файловых систем в виде строковых объектов становится несколько корявым, поскольку используется несколько вызовов os.path.join()
, os.getcwd()
и так далее. Во избежание данной проблемы модуль Pathlib предлагает набор классов, что могут использоваться для популярных операций с путами через более читабельный, простой, объектно-ориентированный способ.
Попробуем переписать вышеуказанный код с модулем Pathlib:
from pathlib import Path outpath = Path.cwd() / ‘output’ outpath_tmp = Path.cwd() / ‘output_tmp’ generate_data(output_tmp) if outpath_tmp.stat().st_size: outpath_tmp.rename(outpath) else: # Ничего не производится Path_tmp.unlink() |
При использовании Pathlib os.getcwd()
становится Path.cwd()
, а оператор '/'
нужен для объединения путей на месте os.path.join
. Вместе с модулем Pathlib можно значительно упростить код, задействуя операторы и вызовы метода.
Популярные методы и их предназначение:
Path.cwd()
: Возвращает путь объекта текущей рабочей директории;Path.home()
: Возвращает путь объекта домашней директории;Path.stat()
: Возвращает информацию о пути;Path.chmod()
: Меняет режим и уровень доступа файла;Path.glob(pattern)
: Получение всех файлов которые соответствую паттерну, например*.jpg
(все картинки) или*.mp3
(все песни);Path.mkdir()
: создает новую папку по данному пути;Path.open()
: Открывает файл, созданный в пути;Path.rename()
: Переименовывает файл или директорию указанной цели;Path.rmdir()
: Удаляет пустую директорию;Path.unlink()
: Удаляет файл или символическую ссылку.
Генерация кроссплатформенных путей в Pathlib
Пути используют разные соглашения в разных операционных системах. Windows использует обратный слеш между названиями папок, тогда как все другие популярные операционные системы используют прямой слеш
/
.
Если вы хотите, чтобы ваш код работал, независимо от базовой ОС, вам нужно будет обрабатывать различные соглашения, характерные для базовой платформы. Модуль Pathlib упрощает работу с путями к файлам. В Pathlib можно просто передать путь или название файла объекту Path()
, используя слеш, независимо от ОС. Pathlib занимается всем остальным.
pathlib.Path.home() / ‘python’ / ‘samples’ / ‘test_me.py’ |
Объект Path()
конвертирует /
в слеш соответствующий операционной системе. pathlib.Path
может представлять путь Windows или Posix. Кроме того, Pathlib решает многие кросс-функциональные баги, легко обрабатывая пути.
Получение информации о пути в Pathlib
Во время работы с путями зачастую требуется найти родительскую директорию файла/папки или получить символические ссылки. У класса Path есть несколько удобных для этого методов, различные части пути доступны как свойства, что включают следующее:
drive
: строка, что представляет название жесткого диска. К примеру,PureWindowsPath('c:/Program Files/CSV').drive
вернет"C:"
;parts
: возвращает кортеж, что дает доступ к компонентам пути;name
: компонент пути без директории;parent
: последовательность обеспечивает доступ к логическим предкам пути;stem
: финальный компонент пути без суффикса;suffix
: разрешение файла финального компонента;anchor
: часть пути перед директорией./
используется для создания дочерних путей и имитации поведенияos.path.join
;joinpath
: совмещает путь с предоставленными аргументами;match(pattern)
: возвращаетTrue/False
, основываясь на совпадении пути с предоставленным шаблоном поиска.
Например, у нас есть данный путь "/home/projects/pyscripts/python/sample.md"
:
path
: — возвращает PosixPath(‘/home/projects/pyscripts/python/sample.md’);path.parts
: — возвращает (‘/’, ‘home’, ‘projects’, ‘pyscripts’, ‘python’);path.name
: — возвращает ‘sample.md’;path.stem
: — возвращает ‘sample’;path.suffix
: — возвращает ‘.md’;path.parent
: — возвращает PosixPath(‘/home/projects/pyscripts/python’);path.parent.parent
: — возвращает PosixPath(‘/home/projects/pyscripts’);path.match('*.md')
: возвращает True;PurePosixPath('/python').joinpath('edited_version')
: возвращает (‘home/projects/pyscripts/python/edited_version.
Альтернатива для модуля glob
Помимо модулей os
, os.path
в Python также доступен модуль glob
, что предоставляет путь связанных утилит. Функция glob.glob
модуля glob
используется для нахождения файлов, соответствующих шаблону.
from glob import glob top_xlsx_files = glob(‘*.xlsx’) # Все файлы с расширением .xlsx all_xlsx_files = glob(‘**/*.xlsx’, recursive=True) |
Pathlib предоставляет свою реализацию glob
:
from pathlib import Path top_xlsx_files = Path.cwd().glob(‘*.xlsx’) all_xlsx_files = Path.cwd().rglob(‘*.xlsx’) |
Функциональность glob доступна с объектами Path
. Следовательно, модуль Pathlib упрощают сложные задачи.
Чтение и запись файлов с использованием Pathlib
Следующие методы используются для выполнения основных операций, таких как чтение и запись файлов:
read_text
: Файл открывается в текстовом режиме для чтения содержимого файла и его закрытия после чтения;read_bytes
: Используется для открытия файла в бинарном режиме, возвращения содержимого в бинарном форме и последующего закрытия файла;write_text
: Используется для открытия файла, записи туда текста и последующего закрытия;write_bytes
: Используется для записи бинарных данных в файл и закрытия файла по завершении процесса.
Давайте испытаем модуль Pathlib используя популярные файловые операции. Следующий пример используется для чтения содержимого файла:
path = pathlib.Path.cwd() / ‘Pathlib.md’ path.read_text() |
Метод read_text()
для объекта Path
используется для чтения содержимого файла. В примере ниже данные записываются в файл, в текстовом режиме:
from pathlib import Path p = Path(‘sample_text_file’) p.write_text(‘Образец данных для записи в файл’) |
Таким образом, в модуле Pathlib наличие пути в качестве объекта позволяет выполнять полезные действия над объектами для файловой системы, включая множество манипуляций с путями, таких как создание или удаление каталогов, поиск определенных файлов, перемещение файлов и так далее.
Заключение
Модуль Pathlib предоставляет огромное количество полезных функций, которые можно использовать для выполнения различных операций, связанных с путями. В качестве дополнительного преимущества библиотека согласовывается с операционной системой.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»