Jak v Pythonu pracovat se složkami rychle a efektivně

Python

Co je adresář a složka v Pythonu

V programování, a zejména v jazyce Python, se velmi často setkáváme s pojmy jako adresář a složka. Ačkoliv tyto dva termíny mnoho lidí používá jako synonyma, je dobré rozumět tomu, co přesně znamenají a jak s nimi Python pracuje. Adresář je v podstatě organizační jednotka souborového systému, která umožňuje ukládat soubory a další adresáře na disku počítače. Složka je pak pouze jiný název pro totéž – jde o vizuální reprezentaci adresáře, se kterou se setkáváme především v grafickém prostředí operačního systému, například ve Finderu na macOS nebo v Průzkumníku souborů ve Windows.

Z technického pohledu je adresář speciální typ souboru, který obsahuje seznam odkazů na jiné soubory nebo adresáře. Tento seznam se nazývá obsah adresáře a každý záznam v něm nese informace o názvu souboru nebo podadresáře, jeho umístění na disku a dalších metadatech. Operační systémy jako Linux, Windows nebo macOS organizují soubory právě prostřednictvím hierarchické struktury adresářů, kde na vrcholu stojí takzvaný kořenový adresář.

Python nabízí velmi bohaté možnosti pro práci s adresáři a složkami. Základním nástrojem je modul os, který je součástí standardní knihovny Pythonu a poskytuje funkce pro interakci s operačním systémem. Pomocí tohoto modulu lze vytvářet nové adresáře, procházet existující, mazat je nebo zjišťovat jejich obsah. Dalším velmi oblíbeným modulem je pathlib, který byl do Pythonu přidán ve verzi 3.4 a přináší objektově orientovaný přístup k práci se souborovým systémem. Mnoho programátorů dnes preferuje právě pathlib, protože kód napsaný s jeho pomocí je čitelnější a přehlednější.

Když Python pracuje se soubory a adresáři, vždy operuje v rámci takzvaného pracovního adresáře, což je adresář, ze kterého byl skript spuštěn nebo ve kterém Python aktuálně „stojí. Tento pracovní adresář lze zjistit pomocí funkce os.getcwd(), kde zkratka cwd znamená current working directory. Změnit pracovní adresář pak lze pomocí funkce os.chdir(), které předáme cestu k adresáři, do kterého se chceme přesunout.

Cesty k adresářům mohou být absolutní nebo relativní. Absolutní cesta popisuje přesnou polohu adresáře od kořenového adresáře souborového systému, například /home/uzivatel/dokumenty na Linuxu nebo C:\Users\uzivatel\dokumenty na Windows. Relativní cesta naproti tomu popisuje polohu adresáře vzhledem k aktuálnímu pracovnímu adresáři. Pokud se tedy nacházíme v adresáři /home/uzivatel a chceme přistoupit k adresáři dokumenty, stačí použít relativní cestu dokumenty bez nutnosti uvádět celou absolutní cestu.

Důležitým konceptem je také hierarchická struktura adresářů, která tvoří stromovou strukturu. Každý adresář může obsahovat libovolný počet souborů a podadresářů, přičemž podadresáře mohou opět obsahovat další soubory a podadresáře. Tato struktura umožňuje logicky organizovat velké množství souborů a usnadňuje orientaci v projektu. V Pythonu lze tuto strukturu procházet rekurzivně pomocí funkce os.walk(), která prochází celý strom adresářů a pro každý adresář vrací jeho název, seznam podadresářů a seznam souborů.

Při práci s adresáři v Pythonu je také důležité myslet na přenositelnost kódu mezi různými operačními systémy. Windows používá jako oddělovač cesty zpětné lomítko, zatímco Linux a macOS používají lomítko. Python tento problém řeší pomocí modulu os.path nebo moderněji pomocí pathlib, které automaticky používají správný oddělovač pro daný operační systém. Díky tomu lze psát kód, který funguje správně na všech platformách bez nutnosti ručně ošetřovat rozdíly mezi operačními systémy.

Rozdíl mezi adresářem a pracovním adresářem

V Pythonu se velmi často setkáváme s pojmy, které na první pohled vypadají podobně, ale ve skutečnosti znamenají něco jiného. Jedním z takových případů je rozdíl mezi adresářem a pracovním adresářem. Mnoho začátečníků tyto dva pojmy zaměňuje, což pak vede k nejrůznějším chybám při práci se soubory a cestami v programu.

Adresář, neboli složka, je jednoduše řečeno místo v souborovém systému operačního systému, kde jsou uloženy soubory nebo jiné adresáře. Může se nacházet kdekoliv na disku, ať už je to na cestě `/home/uzivatel/dokumenty` v Linuxu nebo `C:\Users\Uzivatel\Dokumenty` ve Windows. Adresář jako takový existuje nezávisle na tom, jaký program právě běží nebo odkud byl spuštěn. Je to prostě fyzické místo, kde data leží.

Pracovní adresář je ale něco jiného. Pracovní adresář, anglicky „working directory nebo také „current working directory (zkráceně CWD), je adresář, ve kterém Python aktuálně „stojí a ze kterého vychází při hledání souborů, pokud mu nezadáme absolutní cestu. Jinými slovy, je to výchozí bod pro všechny relativní cesty, které v programu používáme.

Představte si to takto: máte velký dům s mnoha místnostmi. Adresář je jakákoliv konkrétní místnost v tomto domě. Pracovní adresář je pak ta místnost, ve které právě stojíte. Pokud chcete jít do kuchyně, záleží na tom, kde právě jste. Pokud stojíte v obýváku, cesta do kuchyně je jiná, než kdybyste stáli na chodbě.

V Pythonu lze zjistit aktuální pracovní adresář pomocí modulu `os`. Konkrétně funkce `os.getcwd()` vrátí řetězec s cestou k aktuálnímu pracovnímu adresáři. Pokud chcete pracovní adresář změnit, použijete funkci `os.chdir()`, do které předáte cestu k adresáři, do kterého se chcete přesunout. Tato změna pak platí po celou dobu běhu programu, dokud ji opět nezměníte.

Problém nastává ve chvíli, kdy spouštíte Python skript z jiného místa, než kde se skript fyzicky nachází. Pracovní adresář totiž není automaticky nastaven na adresář, ve kterém leží váš skript, ale na adresář, ze kterého byl příkaz ke spuštění zadán. To je zdroj mnoha záludných chyb, kdy program říká, že soubor nebyl nalezen, přestože víte, že vedle skriptu leží. Skript ho hledá v pracovním adresáři, ale soubor je ve složce skriptu, a to jsou dvě různá místa.

Pokud chcete pracovat vždy relativně ke složce, kde se nachází váš skript, a ne k pracovnímu adresáři, můžete využít speciální proměnnou `__file__`, která obsahuje cestu k aktuálně spuštěnému souboru. Kombinací s funkcemi z modulu `os.path`, jako je `os.path.dirname()` nebo `os.path.abspath()`, pak získáte absolutní cestu ke složce skriptu a můžete se na ni vždy spolehnout bez ohledu na to, odkud byl program spuštěn.

Rozdíl mezi adresářem a pracovním adresářem je tedy zásadní zejména při práci s relativními cestami. Relativní cesta jako `data/soubor.txt` neznamená „hledej v adresáři, kde leží skript, ale „hledej v aktuálním pracovním adresáři. Pokud tyto dva adresáře nejsou totožné, program soubor nenajde a vyhodí chybu `FileNotFoundError`. Pochopení tohoto rozdílu vám ušetří hodiny ladění a zbytečné frustrace při vývoji aplikací v Pythonu.

Modul os pro práci se složkami

Práce se souborovým systémem patří k základním dovednostem každého programátora, a Python v tomto ohledu nabízí velmi silné nástroje. Jedním z nejdůležitějších je modul os, který umožňuje interagovat s operačním systémem přímo z kódu. Tento modul je součástí standardní knihovny Pythonu, takže ho není třeba instalovat zvlášť — stačí ho jednoduše importovat pomocí příkazu import os a okamžitě máte k dispozici celou řadu funkcí pro práci se složkami, soubory a cestami.

Srovnání správců souborů a adresářové struktury v Pythonu
Vlastnost os modul pathlib modul shutil modul
Dostupnost od verze Pythonu Python 1.x Python 3.4 Python 2.x
Vytvoření adresáře os.mkdir() Path.mkdir() není přímá podpora
Smazání adresáře os.rmdir() Path.rmdir() shutil.rmtree()
Přejmenování složky os.rename() Path.rename() shutil.move()
Kopírování adresáře není přímá podpora není přímá podpora shutil.copytree()
Výpis obsahu adresáře os.listdir() Path.iterdir() není přímá podpora
Objektově orientovaný přístup Ne Ano Částečně
Práce s cestami napříč OS os.path PurePosixPath / PureWindowsPath závisí na os.path
Rekurzivní procházení adresářů os.walk() Path.rglob() není přímá podpora
Doporučení pro nové projekty Ano (základní operace) Ano (moderní přístup) Ano (hromadné operace)

Nejčastěji používanou funkcí při práci s adresáři je bezpochyby os.getcwd(), která vrátí aktuální pracovní adresář. To se hodí například tehdy, když potřebujete zjistit, ze které složky váš skript právě běží. Výsledkem je řetězec obsahující absolutní cestu, třeba něco jako /home/uzivatel/projekty na Linuxu nebo C:\Users\uzivatel\projekty na Windows. Modul os je navržen tak, aby fungoval napříč různými operačními systémy, takže nemusíte řešit rozdíly v oddělovačích cest — Python se o to postará sám.

Pokud chcete změnit aktuální pracovní adresář, použijete funkci os.chdir(), které předáte cestu k požadované složce jako argument. Tato operace je nenápadná, ale velmi užitečná, zejména ve skriptech, které pracují s více různými adresáři najednou. Nezapomeňte ale, že změna adresáře pomocí os.chdir() ovlivní celý běžící proces, takže pokud pracujete ve větším projektu, může to mít nečekané vedlejší efekty.

Vytváření nových složek je záležitostí funkce os.mkdir(). Tato funkce vytvoří jednu složku na zadané cestě, ale pokud chcete vytvořit celou hierarchii adresářů najednou, sáhnete po os.makedirs(). Rozdíl je zásadní — os.mkdir() selže, pokud nadřazená složka neexistuje, zatímco os.makedirs() celou strukturu vytvoří od základu. Při použití os.makedirs() se hodí parametr exist_ok=True, který zajistí, že funkce nevyhodí výjimku, pokud složka již existuje.

Pro výpis obsahu adresáře slouží funkce os.listdir(), která vrátí seznam všech souborů a podsložek v daném adresáři. Výsledkem je prostý seznam řetězců, takže pokud potřebujete rozlišit, co je soubor a co je složka, musíte použít další funkce jako os.path.isdir() nebo os.path.isfile(). Tyto pomocné funkce z podmodulu os.path jsou naprosto nepostradatelné při jakékoli práci se souborovým systémem.

Mazání složek se provádí pomocí os.rmdir(), ale tato funkce odstraní pouze prázdnou složku. Pokud složka obsahuje soubory nebo podsložky, funkce selže s chybou. V takovém případě je lepší sáhnout po modulu shutil a jeho funkci shutil.rmtree(), která smaže celý adresářový strom bez ohledu na obsah. Při používání těchto funkcí je samozřejmě nutná opatrnost, protože smazané soubory se v Pythonu standardně nepřesouvají do koše.

Velmi praktická je také funkce os.walk(), která umožňuje rekurzivně procházet celou adresářovou strukturu. Funguje jako generátor a pro každý adresář vrátí trojici obsahující cestu k aktuálnímu adresáři, seznam jeho podsložek a seznam souborů v něm. Díky tomu lze snadno projít celý strom složek a provést s každým souborem nebo adresářem libovolnou operaci — přejmenovat ho, zkopírovat, analyzovat nebo třeba spočítat celkovou velikost všech souborů.

Přejmenování souborů a složek zajišťuje funkce os.rename(), které předáte původní a nový název. Tato funkce funguje jak pro soubory, tak pro adresáře, a pokud zadáte cestu do jiného umístění, provede se zároveň přesun. Pozor ale na to, že cílová složka musí existovat, jinak Python vyhodí výjimku FileNotFoundError.

Modul os také nabízí přístup k proměnným prostředí přes os.environ, ale to už je trochu jiná kapitola. Co se týče práce se složkami, je tento modul skutečně komplexní a pokrývá naprostou většinu situací, se kterými se programátor při vývoji setká. Kombinace os, os.path a případně pathlib — modernějšího přístupu k práci s cestami — dává vývojáři v Pythonu velmi silné nástroje pro správu souborového systému bez nutnosti sahat po externích knihovnách.

Vytvoření nové složky pomocí os.mkdir

V Pythonu existuje několik způsobů, jak pracovat se souborovým systémem, a jedním z nejzákladnějších úkonů je vytvoření nové složky. K tomuto účelu slouží funkce os.mkdir(), která je součástí standardní knihovny Pythonu a nachází se v modulu `os`. Tento modul poskytuje rozhraní pro interakci s operačním systémem a umožňuje vývojářům pracovat se soubory, adresáři a dalšími systémovými prostředky přímo z kódu.

Aby bylo možné funkci os.mkdir() použít, je nejprve nutné importovat modul `os`. To se provede jednoduše příkazem import os na začátku skriptu. Bez tohoto importu by Python funkci neznal a vrátil by chybu. Po importu je možné funkci volat a předat jí jako argument cestu k adresáři, který chceme vytvořit. Například příkaz os.mkdir(nova_slozka) vytvoří novou složku s názvem `nova_slozka` v aktuálním pracovním adresáři.

Důležité je si uvědomit, že funkce os.mkdir() vytvoří pouze jeden adresář najednou. Pokud tedy chcete vytvořit strukturu vnořených složek, například `rodic/dite/vnuk`, a přičemž složka `rodic` ještě neexistuje, funkce selže a vyvolá výjimku FileNotFoundError. V takovém případě je vhodnější použít funkci os.makedirs(), která dokáže vytvořit celou hierarchii adresářů najednou, pokud zadáte parametr `exist_ok=True`.

Při práci s funkcí os.mkdir() je velmi důležité ošetřit možné výjimky. Pokud se pokusíte vytvořit složku, která již existuje, Python vyvolá výjimku FileExistsError. Proto je dobrým zvykem obalit volání funkce blokem try-except, který tuto situaci zachytí a program nezhroutí. Například:

try:

os.mkdir(nova_slozka)

except FileExistsError:

print(Složka již existuje.)

Tímto způsobem zajistíte, že váš program bude robustní a odolný vůči chybám. Ošetření výjimek je obecně dobrá programátorská praxe a v případě práce se souborovým systémem je naprosto nezbytná, protože situace na disku se může měnit nezávisle na vašem programu.

Dalším aspektem, na který je třeba myslet, jsou oprávnění souborového systému. Funkce os.mkdir() přijímá volitelný druhý argument `mode`, který určuje přístupová práva nově vytvořeného adresáře. Výchozí hodnota je `0o777`, což znamená plná práva pro vlastníka, skupinu i ostatní uživatele. Na systémech Unix a Linux se tato hodnota kombinuje s aktuální hodnotou `umask`, takže výsledná práva mohou být odlišná od zadané hodnoty. Na systémech Windows je tento parametr ignorován, protože Windows používá jiný systém správy oprávnění.

Pokud pracujete s cestami, je vhodné využívat modul os.path nebo modernější alternativu v podobě modulu pathlib. Tyto moduly umožňují skládat cesty způsobem, který je nezávislý na operačním systému. Například místo ručního psaní lomítek nebo zpětných lomítek lze použít funkci os.path.join(), která automaticky vloží správný oddělovač cesty podle aktuálního operačního systému. To je zvláště důležité při vývoji kódu, který má fungovat jak na Windows, tak na Linuxu nebo macOS.

Moderní přístup k vytváření adresářů v Pythonu nabízí také třída `Path` z modulu `pathlib`, která byla zavedena v Pythonu 3.4. Pomocí metody `Path.mkdir()` lze vytvořit adresář velmi elegantně a čitelně. Navíc tato metoda podporuje parametry `parents=True` a `exist_ok=True`, které řeší problémy s chybějícími nadřazenými adresáři a již existujícími složkami. I přesto zůstává os.mkdir() velmi rozšířenou a oblíbenou volbou, zejména v starším kódu a v situacích, kdy vývojáři preferují práci s tradičním modulem `os`.

Celkově lze říci, že funkce os.mkdir() je základním nástrojem každého Python vývojáře, který pracuje se souborovým systémem. Její správné použití, kombinované s ošetřením výjimek a správnou prací s cestami, zajistí spolehlivé a přenositelné chování vašeho programu napříč různými operačními systémy a prostředími.

Vytvoření více vnořených složek najednou

Při práci s Pythonem se velmi často dostaneme do situace, kdy potřebujeme vytvořit celou strukturu adresářů najednou, nikoliv jen jednu jednoduchou složku. Představte si například projekt, kde potřebujete připravit kompletní adresářovou hierarchii pro ukládání dat, logů a konfiguračních souborů. Ruční vytváření každé složky zvlášť by bylo zdlouhavé a neefektivní. Naštěstí Python nabízí elegantní způsoby, jak tuto situaci řešit.

Nejpoužívanějším nástrojem pro tvorbu vnořených složek v Pythonu je funkce os.makedirs(), která pochází z modulu os. Na rozdíl od funkce os.mkdir(), která dokáže vytvořit pouze jednu složku a selže v případě, že nadřazená složka neexistuje, funkce os.makedirs() vytvoří celou cestu adresářů včetně všech mezilehlých složek. To je klíčový rozdíl, který z ní dělá ideální volbu pro vytváření komplexních adresářových struktur.

Základní použití vypadá takto: pokud chceme vytvořit strukturu jako například projekt/data/vstupni_soubory, stačí napsat jediný příkaz a Python se postará o vytvoření všech potřebných složek na cestě. Bez funkce makedirs bychom museli nejprve vytvořit složku projekt, poté složku data uvnitř ní a nakonec složku vstupni_soubory. S makedirs to zvládneme jedním voláním.

Velmi důležitým parametrem, který byste při práci s touto funkcí neměli opomíjet, je exist_ok=True. Tento parametr říká Pythonu, aby nevyvolával chybu v případě, že složka nebo část cesty již existuje. Ve výchozím nastavení, tedy bez tohoto parametru, funkce os.makedirs() vyhodí výjimku FileExistsError, pokud cílová složka již na disku existuje. V praxi to může způsobit pád celého skriptu, což rozhodně nechceme. Nastavením exist_ok=True se tomuto problému elegantně vyhneme a skript poběží bez problémů bez ohledu na to, zda složky existují nebo ne.

Moderní Python, konkrétně verze 3.4 a novější, přinesl ještě jeden způsob, jak pracovat s adresáři a soubory, a to prostřednictvím modulu pathlib. Tento modul přináší objektově orientovaný přístup k práci se souborovým systémem, který je pro mnoho programátorů intuitivnější a čitelnější. Pro vytváření vnořených složek slouží metoda Path.mkdir() s parametry parents=True a exist_ok=True. Parametr parents=True je zde ekvivalentem toho, co dělá os.makedirs() — říká Pythonu, aby vytvořil všechny nadřazené složky, pokud ještě neexistují.

Práce s pathlib je v mnoha ohledech přehlednější. Cestu k adresáři definujeme jako objekt třídy Path, přičemž jednotlivé části cesty můžeme skládat pomocí operátoru lomítko, což je syntakticky velmi čisté a srozumitelné. Výsledný kód je kratší a lépe čitelný, zejména pro vývojáře, kteří přicházejí z jiných programovacích jazyků.

Při vytváření vnořených složek je také dobré myslet na oprávnění souborového systému. Funkce os.makedirs() přijímá volitelný parametr mode, který umožňuje nastavit přístupová práva pro nově vytvořené složky. Tento parametr funguje na unixových systémech jako Linux nebo macOS, kde je správa oprávnění součástí každodenní práce. Na systémech Windows je situace odlišná a parametr mode nemá stejný efekt.

Dalším praktickým aspektem je práce s relativními a absolutními cestami. Python bez problémů zvládne obojí. Pokud předáme relativní cestu, složky se vytvoří relativně vůči aktuálnímu pracovnímu adresáři, který zjistíme pomocí os.getcwd(). Absolutní cesta naopak přesně specifikuje, kde na disku má být adresářová struktura vytvořena, bez ohledu na to, odkud skript spouštíme. V produkčním prostředí je obecně doporučováno používat absolutní cesty, aby se předešlo nejasnostem a potenciálním chybám.

Je také vhodné zmínit, že při dynamickém generování cest, například pokud skládáme cestu z proměnných nebo uživatelských vstupů, bychom měli používat funkci os.path.join() nebo objekty pathlib namísto prostého řetězcového spojování. Tímto způsobem zajistíme kompatibilitu skriptu napříč různými operačními systémy, protože Windows používá zpětné lomítko jako oddělovač cesty, zatímco Linux a macOS používají lomítko dopředu. Funkce os.path.join() a pathlib tento rozdíl automaticky řeší za nás, takže náš kód bude fungovat správně na všech platformách bez nutnosti jakýchkoliv úprav.

Každý python je jako tajná skříňka plná překvapení – nikdy nevíš, co v něm najdeš, dokud ho pořádně neprozkoumáš, a teprve tehdy pochopíš, jak důležité je udržovat pořádek i v těch nejzapadlejších zákoutích svého počítače.

Radovan Šimánek

Výpis obsahu adresáře funkcí os.listdir

Práce se soubory a adresáři patří mezi základní dovednosti každého programátora, který pracuje s Pythonem. Jednou z nejpoužívanějších funkcí pro práci s adresáři je funkce os.listdir(), která umožňuje vypsat obsah libovolného adresáře na disku. Tato funkce je součástí modulu os, který je nutné nejprve importovat pomocí příkazu import os. Bez tohoto importu by Python funkci vůbec neznal a program by skončil chybou.

Samotné použití funkce je velmi jednoduché. Stačí zavolat os.listdir() a jako argument předat cestu k adresáři, jehož obsah chceme zobrazit. Pokud například chceme vypsat obsah aktuálního pracovního adresáře, použijeme tečku jako argument, tedy os.listdir(.). Funkce vrátí seznam, který obsahuje názvy všech souborů a podsložek nacházejících se v daném adresáři. Je důležité si uvědomit, že funkce nerozlišuje mezi soubory a složkami — vrátí prostě vše, co se v daném adresáři nachází, a je pak na programátorovi, aby případně rozlišil, co je soubor a co je složka.

Výsledkem volání os.listdir() je vždy seznam řetězců, přičemž každý řetězec představuje název jednoho záznamu v daném adresáři. Záznamy nejsou seřazeny podle žádného konkrétního pravidla — pořadí závisí na operačním systému a souborovém systému. Pokud potřebujete záznamy seřadit abecedně, je nutné výsledný seznam seřadit pomocí funkce sorted() nebo metody .sort().

Velmi praktické je kombinovat os.listdir() s dalšími funkcemi modulu os. Například pomocí os.path.isfile() a os.path.isdir() lze snadno odfiltrovat pouze soubory nebo pouze složky. Takový přístup se hodí například tehdy, když chcete zpracovat pouze určitý typ souborů v adresáři, nebo naopak rekurzivně procházet strukturu podsložek. V praxi se tato kombinace používá velmi často, protože samotný výpis obsahu adresáře je jen prvním krokem k dalšímu zpracování dat.

Při práci s cestami je dobré pamatovat na to, že os.listdir() vrací pouze samotné názvy souborů a složek, nikoli jejich úplné cesty. Pokud tedy chcete s jednotlivými záznamy dále pracovat, například je otevřít nebo zkontrolovat jejich vlastnosti, musíte si úplnou cestu sestavit sami. K tomu slouží funkce os.path.join(), která správně spojí cestu k adresáři s názvem souboru bez ohledu na operační systém. Toto je zvláště důležité při vývoji přenositelného kódu, který má fungovat na různých platformách jako Windows, Linux nebo macOS.

Pokud funkci os.listdir() zavoláte bez jakéhokoli argumentu, Python automaticky použije aktuální pracovní adresář, což je stejné chování jako při předání tečky jako argumentu. Aktuální pracovní adresář lze zjistit pomocí funkce os.getcwd(), což se hodí například při ladění programu, kdy si nejste jisti, ze které složky Python právě pracuje.

Je také dobré vědět, že funkce os.listdir() nezahrnuje speciální záznamy jako tečka a dvě tečky, které reprezentují aktuální a nadřazený adresář. To je oproti některým jiným nástrojům příjemné chování, protože výsledný seznam je čistší a nemusíte tyto záznamy ručně odfiltrovat.

V novějších verzích Pythonu existuje také alternativa v podobě funkce os.scandir(), která je výkonnější a vrací objekty s více informacemi o každém záznamu. Přesto os.listdir() zůstává velmi oblíbenou volbou díky své jednoduchosti a přímočarosti, zejména v situacích, kdy nepotřebujete žádné pokročilé informace o souborech a stačí vám jejich seznam. Pro začínající programátory je tato funkce ideálním vstupním bodem do světa práce se souborovým systémem v Pythonu.

Přejmenování a přesun složek v Pythonu

Práce se souborovým systémem patří k základním dovednostem každého Python programátora. Ať už vyvíjíte nástroje pro správu souborů, automatizujete zálohovací procesy nebo jen potřebujete přesunout výsledky svého skriptu na jiné místo, dříve nebo později narazíte na potřebu přejmenovat nebo přesunout složky. Python k tomu nabízí hned několik přístupů, přičemž každý má své výhody a specifika.

Nejzákladnějším způsobem, jak přejmenovat složku v Pythonu, je použití modulu os. Konkrétně funkce os.rename() slouží právě k tomuto účelu. Funkce přijímá dva argumenty — původní cestu ke složce a novou cestu. Pokud zadáte pouze jiný název ve stejném adresáři, dojde k přejmenování. Pokud ale zadáte jinou cestu, Python složku přesune. Je to elegantní řešení, které funguje spolehlivě na všech hlavních operačních systémech.

Důležité je vědět, že os.rename() má jedno omezení — pokud cílová cesta leží na jiném souborovém systému nebo jiném diskovém oddílu, funkce selže a vyhodí výjimku. V takovém případě je vhodnější sáhnout po modulu shutil, konkrétně po funkci shutil.move(). Tato funkce je robustnější a zvládne přesun složky i přes hranice různých souborových systémů. Interně nejprve zkusí použít přejmenování, a pokud to není možné, zkopíruje obsah a původní složku smaže.

Moderní alternativou je pak práce s modulem pathlib, který byl do Pythonu přidán ve verzi 3.4 a od té doby si získal velkou oblibu díky svému objektově orientovanému přístupu. Pomocí třídy Path a její metody rename() lze přejmenovat nebo přesunout složku velmi přehledným způsobem. Kód je čitelnější a intuitivnější, zejména pro programátory, kteří přišli z jiných jazyků nebo teprve začínají s Pythonem.

Při práci s přejmenováváním a přesouváním složek je vždy nutné myslet na ošetření chyb. Může se stát, že složka s cílovým názvem již existuje, že nemáte dostatečná oprávnění, nebo že zadaná cesta vůbec neexistuje. Proto je dobrou praxí obalit tyto operace blokem try-except a zachytit výjimky jako FileNotFoundError, PermissionError nebo FileExistsError. Tím zajistíte, že váš program nezhavaruje při neočekávaných situacích a uživatel dostane srozumitelnou chybovou zprávu.

Zvláštní pozornost si zaslouží situace, kdy pracujete s relativními a absolutními cestami. Relativní cesty jsou vztaženy k aktuálnímu pracovnímu adresáři, který lze zjistit pomocí os.getcwd(). Pokud si nejste jisti, kde váš skript běží, je bezpečnější používat absolutní cesty. Ty lze sestavit například kombinací os.path.abspath() nebo pomocí Path(__file__).parent v modulu pathlib, což vám dá cestu k adresáři, ve kterém se nachází samotný skript.

Dalším zajímavým aspektem je hromadné přejmenování složek. Python díky kombinaci funkce os.listdir() nebo os.scandir() a smyčky umožňuje projít všechny podsložky v daném adresáři a přejmenovat je podle určitého vzoru. Například pokud máte složky pojmenované podle data ve formátu DDMMRRRR a chcete je převést na formát RRRRMMDD, stačí napsat krátký skript, který projde všechny složky, extrahuje části názvu a sestaví nový název. Takové automatizace šetří hodiny manuální práce.

Nesmíme zapomenout ani na přesun celých adresářových stromů. Funkce shutil.move() zvládne přesunout složku i se všemi jejími podsložkami a soubory. Pokud chcete pouze zkopírovat celou strukturu a původní ponechat na místě, použijete shutil.copytree(). Tato funkce rekurzivně zkopíruje celý adresářový strom do nového umístění, přičemž zachová strukturu podsložek.

Při automatizaci těchto operací v produkčním prostředí je také vhodné zaznamenávat provedené změny do logu. Python nabízí modul logging, který umožňuje zapisovat informace o přejmenovaných nebo přesunutých složkách do souboru. To se hodí zejména při ladění problémů nebo při auditu změn v souborovém systému. Kombinace kvalitního ošetření chyb a logování dělá z vašeho skriptu spolehlivý nástroj, na který se lze spolehnout i v kritických situacích.

Mazání prázdných i plných adresářů

Práce s adresáři v Pythonu je něco, s čím se dříve nebo později setká každý programátor. Jednou z nejčastějších operací, které budete potřebovat provádět, je mazání složek – ať už prázdných, nebo těch, které obsahují soubory a další podadresáře. Python na to nabízí hned několik různých přístupů, přičemž každý má své specifické využití a je vhodný pro jiné situace.

Začněme tím nejjednodušším případem – mazáním prázdného adresáře. K tomu slouží funkce `os.rmdir()`, která je součástí standardního modulu `os`. Pokud chcete smazat prázdnou složku, stačí importovat modul `os` a zavolat tuto funkci s cestou k adresáři jako argumentem. Vypadá to takto: `os.rmdir(cesta/k/adresari)`. Problém nastane ve chvíli, kdy se pokusíte touto funkcí smazat adresář, který není prázdný. Python v takovém případě vyhodí výjimku `OSError` a operace se neprovede. To je vlastně bezpečnostní mechanismus, který vás chrání před nechtěným smazáním dat.

Pokud ale potřebujete smazat celý adresář včetně jeho obsahu, musíte sáhnout po jiném nástroji. Tím je modul `shutil` a jeho funkce `shutil.rmtree()`. Tato funkce je v Pythonu jednou z nejpoužívanějších pro práci se složkami a umí rekurzivně smazat celý adresářový strom – tedy adresář, všechny jeho podadresáře a veškeré soubory, které se v nich nacházejí. Použití je jednoduché: `shutil.rmtree(cesta/k/adresari)`. Je ale třeba být velmi opatrný, protože tato operace je nevratná. Jakmile adresář smažete pomocí `shutil.rmtree()`, není cesta zpět – data jsou pryč a nelze je obnovit běžnými prostředky.

Dobrou praxí je před samotným mazáním ověřit, zda adresář vůbec existuje. K tomu můžete využít funkci `os.path.exists()` nebo `os.path.isdir()`. Kombinace těchto kontrol s mazáním pak může vypadat například takto:

```python

import os

import shutil

cesta = cesta/k/adresari

if os.path.isdir(cesta):

shutil.rmtree(cesta)

```

Tento přístup je mnohem robustnější a zabrání chybám v případě, že adresář z nějakého důvodu neexistuje.

Od Pythonu 3.4 je k dispozici také modul `pathlib`, který přináší objektově orientovaný přístup k práci se souborovým systémem. Třída `Path` z modulu `pathlib` nabízí metodu `rmdir()`, která funguje stejně jako `os.rmdir()` – tedy smaže pouze prázdný adresář. Pro mazání plného adresáře je pak opět nutné kombinovat `pathlib` s `shutil.rmtree()`, nebo použít jiný přístup.

Zajímavou alternativou, která se v novějších verzích Pythonu stále více prosazuje, je využití kontextových manažerů a ošetření výjimek. Místo explicitní kontroly existence adresáře můžete použít blok `try-except`, který zachytí případné chyby a umožní vám na ně reagovat. Například:

```python

import shutil

try:

shutil.rmtree(cesta/k/adresari)

except FileNotFoundError:

print(Adresář neexistuje.)

except PermissionError:

print(Nemáte oprávnění smazat tento adresář.)

```

Tímto způsobem máte plnou kontrolu nad tím, co se stane v případě různých chybových stavů. Výjimka `PermissionError` je zvláště důležitá na systémech, kde mohou být adresáře chráněny oprávněními – typicky na Linuxu nebo macOS, ale i na Windows.

Při mazání adresářů v reálných projektech se také často setkáte se situací, kdy je třeba smazat pouze obsah adresáře, ale samotný adresář zachovat. V takovém případě je nejjednodušší projít obsah adresáře pomocí `os.listdir()` nebo `os.scandir()` a každý soubor či podadresář smazat zvlášť. Pro soubory se používá `os.remove()` nebo `os.unlink()`, pro podadresáře pak opět `os.rmdir()` nebo `shutil.rmtree()`.

Mazání dočasných adresářů je další běžný případ použití. Python nabízí modul `tempfile`, který umožňuje vytvářet dočasné soubory a složky. Pokud vytvoříte dočasný adresář pomocí `tempfile.mkdtemp()`, je vaší odpovědností ho po skončení práce smazat. Modul `tempfile` také nabízí kontextový manažer `tempfile.TemporaryDirectory()`, který se o mazání postará automaticky po opuštění bloku `with`.

Celkově vzato, Python poskytuje bohatou sadu nástrojů pro mazání jak prázdných, tak plných adresářů. Klíčem k úspěchu je vybrat správný nástroj pro danou situaci, vždy ošetřit možné výjimky a nikdy nepodceňovat nevratnost operace mazání. Dobrý programátor si vždy dvakrát rozmyslí, než spustí `shutil.rmtree()` na důležitou složku.

Modul pathlib jako modernější alternativa

Od verze 3.4 přináší Python modul pathlib, který zásadně mění způsob, jakým vývojáři pracují se souborovým systémem. Zatímco starší přístupy využívaly především modul os a jeho podmodul os.path, pathlib nabízí objektově orientovaný přístup, který je intuitivnější, čitelnější a v mnoha ohledech elegantnější. Pokud jste dosud pracovali se složkami a adresáři pomocí řetězců a funkcí jako os.path.join() nebo os.listdir(), pathlib vás pravděpodobně přesvědčí, že existuje lepší cesta.

Základním stavebním kamenem celého modulu je třída Path. Tato třída reprezentuje cestu v souborovém systému a automaticky se přizpůsobuje operačnímu systému, na kterém kód běží. Na Windows vrátí instanci třídy WindowsPath, na Linuxu nebo macOS pak PosixPath. Vývojář se přitom nemusí starat o tyto detaily, protože vše probíhá transparentně na pozadí. Stačí napsat from pathlib import Path a okamžitě máte k dispozici mocný nástroj pro práci s adresáři a soubory.

Vytvoření objektu reprezentujícího adresář je triviální záležitost. Stačí napsat p = Path('/home/uzivatel/dokumenty') a máte objekt, se kterým můžete dále pracovat. Jednou z největších výhod je možnost skládat cesty pomocí operátoru lomítka, tedy /. Místo zdlouhavého os.path.join('home', 'uzivatel', 'dokumenty', 'projekt') jednoduše napíšete Path('home') / 'uzivatel' / 'dokumenty' / 'projekt'. Výsledek je čitelnější a přirozenější, zvláště pro ty, kteří jsou zvyklí pracovat s cestami v terminálu.

Procházení obsahu adresáře je s pathlib rovněž velmi pohodlné. Metoda iterdir() vrátí iterátor přes všechny položky v daném adresáři, ať už jde o soubory nebo podsložky. Každá vrácená položka je opět objektem třídy Path, takže na ní lze okamžitě volat další metody. Chcete-li zjistit, zda jde o adresář, zavoláte metodu is_dir(), pro soubor pak is_file(). Tato konzistentnost je jedním z důvodů, proč mnoho zkušených Python vývojářů přešlo na pathlib a již se nehodlá vracet.

Pro rekurzivní procházení adresářové struktury slouží metoda rglob(), případně glob() pro prohledávání bez rekurze. Tyto metody přijímají vzor ve stylu shellových globů, takže například p.rglob('*.py') najde všechny Python soubory v celém stromu adresářů pod danou cestou. To je výrazně přehlednější než kombinace os.walk() s manuálním filtrováním souborů.

Vytvoření nového adresáře zvládnete pomocí metody mkdir(). Tato metoda přijímá parametr parents=True, který zajistí vytvoření všech chybějících nadřazených adresářů, a parametr exist_ok=True, díky němuž nevznikne výjimka v případě, že adresář již existuje. Kombinace těchto dvou parametrů nahrazuje celou sérii kontrol, které by jinak bylo nutné provádět ručně.

Velmi praktická je také vlastnost parent, která vrátí nadřazený adresář dané cesty, nebo vlastnost name, jež vrátí samotný název souboru či složky bez celé cesty. Vlastnost stem pak vrátí název bez přípony a suffix samotnou příponu. Tyto atributy výrazně zjednodušují situace, kdy potřebujete pracovat s jednotlivými částmi cesty bez nutnosti psát složité řetězcové operace.

Modul pathlib rovněž umožňuje přímou práci se soubory prostřednictvím metod jako read_text(), write_text(), read_bytes() nebo write_bytes(). Díky tomu lze číst a zapisovat obsah souborů bez nutnosti explicitně otevírat a zavírat souborové deskriptory pomocí konstrukce with open(), ačkoliv i tato klasická metoda zůstává samozřejmě plně funkční a v mnoha situacích opodstatněná.

Přechod na pathlib není jen otázkou estetiky nebo módního trendu. Jde o zásadní zlepšení čitelnosti a udržovatelnosti kódu, zejména v projektech, kde se s adresáři a soubory pracuje intenzivně. Kód napsaný pomocí pathlib je kratší, srozumitelnější a méně náchylný k chybám způsobeným manuální manipulací s řetězci cest. Pokud tedy začínáte nový projekt nebo refaktorujete stávající kód, pathlib by měl být vaší první volbou při práci se souborovým systémem v Pythonu.

Zjištění aktuálního pracovního adresáře

Každý programátor, který pracuje s Pythonem, se dříve nebo později setká s potřebou zjistit, ve kterém adresáři se jeho skript právě nachází nebo odkud je spouštěn. Tato zdánlivě jednoduchá věc má ve skutečnosti několik zajímavých aspektů, které stojí za to důkladně prozkoumat. Pracovní adresář, anglicky označovaný jako current working directory, je základním kamenem každé práce se soubory a složkami v jakémkoliv programovacím jazyce, Python nevyjímaje.

V Pythonu existuje několik způsobů, jak aktuální pracovní adresář zjistit. Nejčastěji používanou metodou je funkce os.getcwd(), která je součástí standardního modulu os. Tento modul je dostupný v každé instalaci Pythonu a není třeba ho nijak zvlášť instalovat. Stačí ho jednoduše importovat na začátku skriptu pomocí příkazu import os a následně zavolat zmíněnou funkci. Výsledkem je řetězec obsahující absolutní cestu k aktuálnímu pracovnímu adresáři, například /home/uzivatel/projekty na Linuxu nebo C:\Users\uzivatel\projekty na Windows.

Je důležité si uvědomit, že aktuální pracovní adresář nemusí být vždy totožný s adresářem, ve kterém se nachází samotný skript. To je chyba, která trápí mnoho začínajících programátorů. Pokud spustíte skript z jiného umístění, než kde je uložen, os.getcwd() vrátí adresář, ze kterého byl skript spuštěn, nikoliv adresář, kde skript fyzicky leží. Toto rozlišení je naprosto zásadní pro správné fungování programů, které pracují se soubory.

Moderní Python nabízí kromě starého dobrého modulu os také elegantnější přístup prostřednictvím modulu pathlib, který byl do Pythonu přidán ve verzi 3.4. Pomocí třídy Path z tohoto modulu lze aktuální pracovní adresář zjistit voláním Path.cwd(). Výsledkem není prostý řetězec, ale objekt typu Path, se kterým se následně pracuje mnohem pohodlněji. Lze s ním snadno spojovat části cest, zjišťovat, zda daná složka existuje, nebo procházet adresářovou strukturu.

Rozdíl mezi těmito dvěma přístupy je především v tom, jak s výsledkem dále pracujete. Zatímco os.getcwd() vrací prostý řetězec, Path.cwd() vrací objekt, který má celou řadu užitečných metod. Například pomocí operátoru lomítko lze jednoduše sestavovat cesty k souborům nebo podsložkám, což je syntakticky mnohem čistší než klasické spojování řetězců.

Při vývoji větších projektů je dobré mít na paměti, že pracovní adresář se může měnit v průběhu běhu programu. Pokud někde v kódu voláte funkci os.chdir(), která pracovní adresář mění, může to mít nečekané důsledky na jiných místech programu. Proto je vhodné aktuální pracovní adresář zjistit vždy čerstvě v místě, kde ho skutečně potřebujete, nebo si ho uložit na začátku programu a dále ho předávat jako parametr funkcím, které ho potřebují.

Dalším praktickým trikem je kombinace zjištění pracovního adresáře s dalšími operacemi nad souborovým systémem. Například můžete snadno vypsat obsah aktuální složky, zkontrolovat existenci konkrétního souboru nebo sestavit absolutní cestu k souboru, jehož název znáte, ale nevíte, kde přesně se nacházíte. Správné pochopení práce s pracovním adresářem je základem pro psaní spolehlivých a přenositelných Python skriptů, které fungují správně na různých operačních systémech i v různých prostředích.

Procházení adresářové struktury pomocí os.walk

Práce se souborovým systémem patří k základním dovednostem každého programátora v Pythonu. Jednou z nejužitečnějších funkcí, které nám standardní knihovna nabízí, je bezpochyby os.walk, která umožňuje procházet celou adresářovou strukturu rekurzivně a bez nutnosti psát vlastní rekurzivní funkce. Pokud jste někdy potřebovali projít složku a všechny její podsložky, abyste například nalezli konkrétní soubory nebo zjistili, co se v daném adresáři nachází, pak je os.walk přesně to, co hledáte.

Funkce os.walk se nachází v modulu os, který musíme nejprve importovat pomocí příkazu import os. Samotné volání funkce je pak velmi jednoduché — stačí předat cestu ke kořenovému adresáři, od kterého chceme procházení zahájit. Funkce vrací generátor, který postupně prochází celou stromovou strukturu adresářů a pro každý adresář vrací trojici hodnot. Tato trojice se skládá z aktuální cesty k adresáři, seznamu podsložek nacházejících se v daném adresáři a seznamu souborů, které se v daném adresáři přímo nacházejí.

Typické použití vypadá takto: iterujeme přes výsledek funkce os.walk a pro každou iteraci rozbalíme trojici do proměnných, které obvykle pojmenováváme root, dirs a files. Proměnná root obsahuje aktuální cestu, dirs je seznam názvů podsložek a files je seznam názvů souborů v dané složce. Je důležité si uvědomit, že názvy v seznamech dirs a files jsou pouze samotné názvy, nikoli úplné cesty. Pokud potřebujeme úplnou cestu k souboru, musíme ji sestavit pomocí os.path.join(root, filename), což je správný a přenositelný způsob spojování cest.

Výchozí chování funkce os.walk je procházení shora dolů, tedy nejprve se zpracuje kořenový adresář, poté jeho podsložky a tak dále do hloubky. Toto chování lze změnit nastavením parametru topdown=False, čímž dosáhneme procházení zdola nahoru. To může být užitečné například v situacích, kdy chceme mazat prázdné adresáře — nejprve musíme zpracovat obsah a teprve poté samotnou složku.

Dalším zajímavým parametrem je onerror, který přijímá funkci, jež se zavolá v případě, že dojde k chybě při přístupu k některému adresáři. Bez tohoto parametru jsou chyby tiše ignorovány, což může být v některých případech nežádoucí, zejména pokud ladíme aplikaci nebo potřebujeme mít jistotu, že jsme prošli skutečně celou strukturu.

Velmi praktickým využitím os.walk je například hledání všech souborů s určitou příponou. Představme si, že máme projekt s desítkami složek a potřebujeme najít všechny soubory s příponou .py. Pomocí os.walk a jednoduché podmínky s metodou endswith() nebo pomocí modulu fnmatch to zvládneme v několika řádcích kódu. Podobně lze snadno spočítat celkovou velikost adresáře — pro každý soubor zjistíme jeho velikost pomocí os.path.getsize() a všechny hodnoty sečteme.

Je také dobré vědět, že modifikace seznamu dirs přímo v průběhu iterace má reálný vliv na to, které podsložky budou navštíveny. Pokud tedy z tohoto seznamu odstraníme určité položky, os.walk do těchto podsložek nevstoupí. To je velmi mocný nástroj, když chceme například přeskočit skryté složky začínající tečkou nebo složky s názvem node_modules či __pycache__, které obvykle neobsahují nic, co bychom chtěli zpracovávat.

os.walk je jednou z těch funkcí, které výrazně zjednodušují práci se souborovým systémem a šetří programátorovi spoustu času. Alternativou v moderním Pythonu je použití třídy pathlib.Path a její metody rglob(), která nabízí podobnou funkcionalitu s objektově orientovaným přístupem. Nicméně os.walk zůstává velmi populární a hojně používanou funkcí, na kterou narazíte v nespočtu projektů a kódových bází.

Časté chyby při manipulaci se složkami

Práce se složkami v Pythonu se na první pohled může zdát jako jednoduchá záležitost, ale zkušení vývojáři dobře vědí, že právě tato oblast skrývá celou řadu pastí, do kterých je velmi snadné spadnout. Jednou z nejrozšířenějších chyb je používání pevně zakódovaných cest, tedy situace, kdy programátor napíše do kódu absolutní cestu ve stylu `/home/uzivatel/dokumenty/projekt` nebo `C:\Users\uzivatel\dokumenty\projekt`. Takový kód funguje výhradně na konkrétním počítači a ve chvíli, kdy ho spustí někdo jiný nebo kdy ho přenesete na server, celý program selže. Správným přístupem je používat relativní cesty nebo dynamicky zjišťovat aktuální pracovní adresář pomocí `os.getcwd()` nebo modulu `pathlib`.

Další velmi běžnou chybou je ignorování rozdílů mezi operačními systémy při práci s oddělovači cest. Windows používá zpětné lomítko `\`, zatímco Linux a macOS používají dopředné lomítko `/`. Mnoho začátečníků skládá cesty ručně pomocí řetězcové konkatenace, například `slozka + \\ + soubor`, což je přesně ten způsob, který způsobuje problémy při přenositelnosti kódu. Python pro tyto účely nabízí funkci `os.path.join()` nebo moderní přístup přes `pathlib.Path`, které se o správný oddělovač postarají automaticky bez ohledu na platformu.

Velmi záludnou chybou je také předpokládání existence složky bez předchozího ověření. Pokud se pokusíte vytvořit soubor ve složce, která neexistuje, Python vyhodí výjimku `FileNotFoundError`. Podobně pokud se pokusíte smazat nebo přejmenovat složku, která mezitím byla odstraněna jiným procesem, skript havaruje. Proto je vždy nutné buď explicitně ověřit existenci adresáře pomocí `os.path.exists()` nebo `Path.exists()`, nebo použít parametr `exist_ok=True` při volání `os.makedirs()`, který zajistí, že vytvoření složky neselže, pokud již existuje.

Dalším problémem, na který naráží zejména méně zkušení vývojáři, je záměna relativní a absolutní cesty v kontextu spouštěného skriptu. Relativní cesta se totiž nevztahuje k umístění samotného skriptu, ale k aktuálnímu pracovnímu adresáři procesu. To znamená, že pokud spustíte skript z jiného adresáře, než ve kterém se nachází, relativní cesty budou ukazovat úplně jinam, než jste zamýšleli. Řešením je používat `__file__` pro zjištění umístění aktuálního skriptu a od něj odvozovat potřebné cesty, například takto: `os.path.dirname(os.path.abspath(__file__))`.

Nesmíme zapomenout ani na problémy s oprávněními. Pokus o vytvoření složky v systémovém adresáři bez administrátorských práv skončí výjimkou `PermissionError`. Stejně tak mazání složek, ke kterým nemá aktuální uživatel přístup, způsobí pád programu. Správně napsaný kód by měl tyto situace ošetřovat pomocí bloků `try-except` a uživateli poskytnout srozumitelnou zprávu o tom, co se stalo.

Velmi podceňovanou chybou je nesprávné mazání adresářů obsahujících soubory. Funkce `os.rmdir()` dokáže smazat pouze prázdný adresář. Pokud se pokusíte touto funkcí odstranit složku, která obsahuje soubory nebo podsložky, Python vyhodí výjimku `OSError`. Pro rekurzivní mazání celého adresářového stromu je třeba použít `shutil.rmtree()`, ale i tuto funkci je nutné používat s rozvahou, protože smazané soubory nelze jednoduše obnovit.

Časté přehlédnutí nastává také při práci s cestami obsahujícími mezery nebo speciální znaky, jako jsou háčky a čárky v českém prostředí. Ačkoli moderní Python s těmito znaky pracuje bez problémů díky podpoře Unicode, starší kód nebo externí nástroje volané přes `subprocess` mohou mít s takovými cestami potíže. Vždy je proto dobré testovat kód s realistickými daty, která odpovídají skutečnému prostředí nasazení.

Publikováno: 11. 06. 2026

Kategorie: Programování a vývoj