[{"data":1,"prerenderedAt":902},["ShallowReactive",2],{"blog-\u002Fblog\u002Fpython-files-pathlib-explained":3},{"id":4,"title":5,"body":6,"description":888,"difficulty":889,"extension":890,"framework":891,"frameworkSlug":39,"meta":892,"navigation":188,"order":92,"path":893,"qaPath":894,"seo":895,"stem":896,"subtopic":897,"topic":898,"topicSlug":899,"updated":900,"__hash__":901},"blog\u002Fblog\u002Fpython-files-pathlib-explained.md","Python Files & pathlib Explained — Reading, Writing, and Modern Path Handling",{"type":7,"value":8,"toc":878},"minimark",[9,14,23,27,34,108,117,121,144,243,246,250,270,397,403,407,420,513,526,530,540,638,647,651,664,779,795,799,874],[10,11,13],"h2",{"id":12},"python-files-pathlib-explained","Python files & pathlib, explained",[15,16,17,18,22],"p",{},"Reading and writing files is everyday work, and modern Python makes it clean: context\nmanagers guarantee files are closed, and ",[19,20,21],"code",{},"pathlib"," replaces fragile path-string manipulation\nwith real objects. Here's the idiomatic way to handle both.",[10,24,26],{"id":25},"open-files-with-a-context-manager","Open files with a context manager",[15,28,29,30,33],{},"Always open files with ",[19,31,32],{},"with",". The context manager closes the file automatically — even if an\nexception is raised mid-read — so you never leak handles or lose buffered writes.",[35,36,41],"pre",{"className":37,"code":38,"language":39,"meta":40,"style":40},"language-python shiki shiki-themes github-light github-dark","with open(\"data.txt\", \"r\", encoding=\"utf-8\") as f:\n    content = f.read()\n# file is guaranteed closed here, exception or not\n","python","",[19,42,43,90,101],{"__ignoreMap":40},[44,45,48,51,55,59,63,66,69,71,75,78,81,84,87],"span",{"class":46,"line":47},"line",1,[44,49,32],{"class":50},"szBVR",[44,52,54],{"class":53},"sj4cs"," open",[44,56,58],{"class":57},"sVt8B","(",[44,60,62],{"class":61},"sZZnC","\"data.txt\"",[44,64,65],{"class":57},", ",[44,67,68],{"class":61},"\"r\"",[44,70,65],{"class":57},[44,72,74],{"class":73},"s4XuR","encoding",[44,76,77],{"class":50},"=",[44,79,80],{"class":61},"\"utf-8\"",[44,82,83],{"class":57},") ",[44,85,86],{"class":50},"as",[44,88,89],{"class":57}," f:\n",[44,91,93,96,98],{"class":46,"line":92},2,[44,94,95],{"class":57},"    content ",[44,97,77],{"class":50},[44,99,100],{"class":57}," f.read()\n",[44,102,104],{"class":46,"line":103},3,[44,105,107],{"class":106},"sJ8bj","# file is guaranteed closed here, exception or not\n",[15,109,110,111,113,114,116],{},"Specify ",[19,112,74],{}," explicitly (almost always ",[19,115,80],{},"); relying on the platform default is a\nclassic source of \"works on my machine\" text bugs.",[10,118,120],{"id":119},"file-modes-and-reading-patterns","File modes and reading patterns",[15,122,123,124,127,128,131,132,135,136,139,140,143],{},"The mode string controls intent: ",[19,125,126],{},"r"," read, ",[19,129,130],{},"w"," write (truncates!), ",[19,133,134],{},"a"," append, ",[19,137,138],{},"x"," create-or-\nfail, and a trailing ",[19,141,142],{},"b"," for binary. There are several ways to read.",[35,145,147],{"className":37,"code":146,"language":39,"meta":40,"style":40},"with open(\"data.txt\") as f:\n    whole = f.read()            # entire file as one string\n    # f.readlines() → list of lines\n\nwith open(\"big.log\") as f:\n    for line in f:              # streams line by line — memory-efficient\n        process(line.rstrip(\"\\n\"))\n",[19,148,149,165,178,183,190,208,226],{"__ignoreMap":40},[44,150,151,153,155,157,159,161,163],{"class":46,"line":47},[44,152,32],{"class":50},[44,154,54],{"class":53},[44,156,58],{"class":57},[44,158,62],{"class":61},[44,160,83],{"class":57},[44,162,86],{"class":50},[44,164,89],{"class":57},[44,166,167,170,172,175],{"class":46,"line":92},[44,168,169],{"class":57},"    whole ",[44,171,77],{"class":50},[44,173,174],{"class":57}," f.read()            ",[44,176,177],{"class":106},"# entire file as one string\n",[44,179,180],{"class":46,"line":103},[44,181,182],{"class":106},"    # f.readlines() → list of lines\n",[44,184,186],{"class":46,"line":185},4,[44,187,189],{"emptyLinePlaceholder":188},true,"\n",[44,191,193,195,197,199,202,204,206],{"class":46,"line":192},5,[44,194,32],{"class":50},[44,196,54],{"class":53},[44,198,58],{"class":57},[44,200,201],{"class":61},"\"big.log\"",[44,203,83],{"class":57},[44,205,86],{"class":50},[44,207,89],{"class":57},[44,209,211,214,217,220,223],{"class":46,"line":210},6,[44,212,213],{"class":50},"    for",[44,215,216],{"class":57}," line ",[44,218,219],{"class":50},"in",[44,221,222],{"class":57}," f:              ",[44,224,225],{"class":106},"# streams line by line — memory-efficient\n",[44,227,229,232,235,238,240],{"class":46,"line":228},7,[44,230,231],{"class":57},"        process(line.rstrip(",[44,233,234],{"class":61},"\"",[44,236,237],{"class":53},"\\n",[44,239,234],{"class":61},[44,241,242],{"class":57},"))\n",[15,244,245],{},"Iterating the file object is the right way to handle large files — it never loads everything\ninto memory.",[10,247,249],{"id":248},"writing-files","Writing files",[15,251,252,254,255,257,258,261,262,265,266,269],{},[19,253,130],{}," overwrites, ",[19,256,134],{}," appends. ",[19,259,260],{},"write"," doesn't add newlines, so include them yourself or use\n",[19,263,264],{},"writelines","\u002F",[19,267,268],{},"print(..., file=f)",".",[35,271,273],{"className":37,"code":272,"language":39,"meta":40,"style":40},"with open(\"out.txt\", \"w\", encoding=\"utf-8\") as f:\n    f.write(\"first line\\n\")\n    f.writelines(f\"{n}\\n\" for n in range(3))\n\nwith open(\"out.txt\", \"a\") as f:\n    f.write(\"appended\\n\")\n",[19,274,275,305,320,359,363,384],{"__ignoreMap":40},[44,276,277,279,281,283,286,288,291,293,295,297,299,301,303],{"class":46,"line":47},[44,278,32],{"class":50},[44,280,54],{"class":53},[44,282,58],{"class":57},[44,284,285],{"class":61},"\"out.txt\"",[44,287,65],{"class":57},[44,289,290],{"class":61},"\"w\"",[44,292,65],{"class":57},[44,294,74],{"class":73},[44,296,77],{"class":50},[44,298,80],{"class":61},[44,300,83],{"class":57},[44,302,86],{"class":50},[44,304,89],{"class":57},[44,306,307,310,313,315,317],{"class":46,"line":92},[44,308,309],{"class":57},"    f.write(",[44,311,312],{"class":61},"\"first line",[44,314,237],{"class":53},[44,316,234],{"class":61},[44,318,319],{"class":57},")\n",[44,321,322,325,328,330,333,336,339,341,344,347,349,352,354,357],{"class":46,"line":103},[44,323,324],{"class":57},"    f.writelines(",[44,326,327],{"class":50},"f",[44,329,234],{"class":61},[44,331,332],{"class":53},"{",[44,334,335],{"class":57},"n",[44,337,338],{"class":53},"}\\n",[44,340,234],{"class":61},[44,342,343],{"class":50}," for",[44,345,346],{"class":57}," n ",[44,348,219],{"class":50},[44,350,351],{"class":53}," range",[44,353,58],{"class":57},[44,355,356],{"class":53},"3",[44,358,242],{"class":57},[44,360,361],{"class":46,"line":185},[44,362,189],{"emptyLinePlaceholder":188},[44,364,365,367,369,371,373,375,378,380,382],{"class":46,"line":192},[44,366,32],{"class":50},[44,368,54],{"class":53},[44,370,58],{"class":57},[44,372,285],{"class":61},[44,374,65],{"class":57},[44,376,377],{"class":61},"\"a\"",[44,379,83],{"class":57},[44,381,86],{"class":50},[44,383,89],{"class":57},[44,385,386,388,391,393,395],{"class":46,"line":210},[44,387,309],{"class":57},[44,389,390],{"class":61},"\"appended",[44,392,237],{"class":53},[44,394,234],{"class":61},[44,396,319],{"class":57},[15,398,399,400,402],{},"Be careful: opening with ",[19,401,290],{}," truncates the file the moment it's opened, even before you\nwrite anything.",[10,404,406],{"id":405},"pathlib-paths-as-objects","pathlib: paths as objects",[15,408,409,412,413,416,417,419],{},[19,410,411],{},"pathlib.Path"," replaces ",[19,414,415],{},"os.path"," string functions with an object-oriented API. The ",[19,418,265],{},"\noperator joins paths portably across operating systems.",[35,421,423],{"className":37,"code":422,"language":39,"meta":40,"style":40},"from pathlib import Path\n\np = Path(\"data\") \u002F \"reports\" \u002F \"june.txt\"   # OS-correct separator\np.name          # 'june.txt'\np.stem          # 'june'\np.suffix        # '.txt'\np.parent        # Path('data\u002Freports')\np.exists()      # True\u002FFalse\n",[19,424,425,439,443,472,480,488,496,504],{"__ignoreMap":40},[44,426,427,430,433,436],{"class":46,"line":47},[44,428,429],{"class":50},"from",[44,431,432],{"class":57}," pathlib ",[44,434,435],{"class":50},"import",[44,437,438],{"class":57}," Path\n",[44,440,441],{"class":46,"line":92},[44,442,189],{"emptyLinePlaceholder":188},[44,444,445,448,450,453,456,458,460,463,466,469],{"class":46,"line":103},[44,446,447],{"class":57},"p ",[44,449,77],{"class":50},[44,451,452],{"class":57}," Path(",[44,454,455],{"class":61},"\"data\"",[44,457,83],{"class":57},[44,459,265],{"class":50},[44,461,462],{"class":61}," \"reports\"",[44,464,465],{"class":50}," \u002F",[44,467,468],{"class":61}," \"june.txt\"",[44,470,471],{"class":106},"   # OS-correct separator\n",[44,473,474,477],{"class":46,"line":185},[44,475,476],{"class":57},"p.name          ",[44,478,479],{"class":106},"# 'june.txt'\n",[44,481,482,485],{"class":46,"line":192},[44,483,484],{"class":57},"p.stem          ",[44,486,487],{"class":106},"# 'june'\n",[44,489,490,493],{"class":46,"line":210},[44,491,492],{"class":57},"p.suffix        ",[44,494,495],{"class":106},"# '.txt'\n",[44,497,498,501],{"class":46,"line":228},[44,499,500],{"class":57},"p.parent        ",[44,502,503],{"class":106},"# Path('data\u002Freports')\n",[44,505,507,510],{"class":46,"line":506},8,[44,508,509],{"class":57},"p.exists()      ",[44,511,512],{"class":106},"# True\u002FFalse\n",[15,514,515,516,65,519,65,522,525],{},"No more ",[19,517,518],{},"os.path.join",[19,520,521],{},"os.path.basename",[19,523,524],{},"os.path.splitext"," — it's all methods and\nproperties on one object.",[10,527,529],{"id":528},"reading-and-writing-with-path","Reading and writing with Path",[15,531,532,535,536,539],{},[19,533,534],{},"Path"," has convenience methods for the common one-shot read\u002Fwrite, so you don't even need\n",[19,537,538],{},"open"," for simple cases.",[35,541,543],{"className":37,"code":542,"language":39,"meta":40,"style":40},"from pathlib import Path\n\np = Path(\"notes.txt\")\np.write_text(\"hello\\n\", encoding=\"utf-8\")    # write whole file\ntext = p.read_text(encoding=\"utf-8\")         # read whole file\ndata = Path(\"img.png\").read_bytes()          # binary read\n",[19,544,545,555,559,572,598,620],{"__ignoreMap":40},[44,546,547,549,551,553],{"class":46,"line":47},[44,548,429],{"class":50},[44,550,432],{"class":57},[44,552,435],{"class":50},[44,554,438],{"class":57},[44,556,557],{"class":46,"line":92},[44,558,189],{"emptyLinePlaceholder":188},[44,560,561,563,565,567,570],{"class":46,"line":103},[44,562,447],{"class":57},[44,564,77],{"class":50},[44,566,452],{"class":57},[44,568,569],{"class":61},"\"notes.txt\"",[44,571,319],{"class":57},[44,573,574,577,580,582,584,586,588,590,592,595],{"class":46,"line":185},[44,575,576],{"class":57},"p.write_text(",[44,578,579],{"class":61},"\"hello",[44,581,237],{"class":53},[44,583,234],{"class":61},[44,585,65],{"class":57},[44,587,74],{"class":73},[44,589,77],{"class":50},[44,591,80],{"class":61},[44,593,594],{"class":57},")    ",[44,596,597],{"class":106},"# write whole file\n",[44,599,600,603,605,608,610,612,614,617],{"class":46,"line":192},[44,601,602],{"class":57},"text ",[44,604,77],{"class":50},[44,606,607],{"class":57}," p.read_text(",[44,609,74],{"class":73},[44,611,77],{"class":50},[44,613,80],{"class":61},[44,615,616],{"class":57},")         ",[44,618,619],{"class":106},"# read whole file\n",[44,621,622,625,627,629,632,635],{"class":46,"line":210},[44,623,624],{"class":57},"data ",[44,626,77],{"class":50},[44,628,452],{"class":57},[44,630,631],{"class":61},"\"img.png\"",[44,633,634],{"class":57},").read_bytes()          ",[44,636,637],{"class":106},"# binary read\n",[15,639,640,641,644,645,269],{},"For larger or streaming work, ",[19,642,643],{},"p.open()"," returns a normal file object you use with ",[19,646,32],{},[10,648,650],{"id":649},"globbing-and-traversing-directories","Globbing and traversing directories",[15,652,653,655,656,659,660,663],{},[19,654,21],{}," makes finding and walking files concise. ",[19,657,658],{},"glob"," matches a pattern in one directory;\n",[19,661,662],{},"rglob"," recurses.",[35,665,667],{"className":37,"code":666,"language":39,"meta":40,"style":40},"from pathlib import Path\n\nfor py in Path(\"src\").rglob(\"*.py\"):     # all .py files, recursively\n    print(py)\n\nPath(\"out\").mkdir(parents=True, exist_ok=True)   # create dirs safely\nPath(\"old.txt\").unlink(missing_ok=True)          # delete if present\n",[19,668,669,679,683,710,718,722,756],{"__ignoreMap":40},[44,670,671,673,675,677],{"class":46,"line":47},[44,672,429],{"class":50},[44,674,432],{"class":57},[44,676,435],{"class":50},[44,678,438],{"class":57},[44,680,681],{"class":46,"line":92},[44,682,189],{"emptyLinePlaceholder":188},[44,684,685,688,691,693,695,698,701,704,707],{"class":46,"line":103},[44,686,687],{"class":50},"for",[44,689,690],{"class":57}," py ",[44,692,219],{"class":50},[44,694,452],{"class":57},[44,696,697],{"class":61},"\"src\"",[44,699,700],{"class":57},").rglob(",[44,702,703],{"class":61},"\"*.py\"",[44,705,706],{"class":57},"):     ",[44,708,709],{"class":106},"# all .py files, recursively\n",[44,711,712,715],{"class":46,"line":185},[44,713,714],{"class":53},"    print",[44,716,717],{"class":57},"(py)\n",[44,719,720],{"class":46,"line":192},[44,721,189],{"emptyLinePlaceholder":188},[44,723,724,727,730,733,736,738,741,743,746,748,750,753],{"class":46,"line":210},[44,725,726],{"class":57},"Path(",[44,728,729],{"class":61},"\"out\"",[44,731,732],{"class":57},").mkdir(",[44,734,735],{"class":73},"parents",[44,737,77],{"class":50},[44,739,740],{"class":53},"True",[44,742,65],{"class":57},[44,744,745],{"class":73},"exist_ok",[44,747,77],{"class":50},[44,749,740],{"class":53},[44,751,752],{"class":57},")   ",[44,754,755],{"class":106},"# create dirs safely\n",[44,757,758,760,763,766,769,771,773,776],{"class":46,"line":228},[44,759,726],{"class":57},[44,761,762],{"class":61},"\"old.txt\"",[44,764,765],{"class":57},").unlink(",[44,767,768],{"class":73},"missing_ok",[44,770,77],{"class":50},[44,772,740],{"class":53},[44,774,775],{"class":57},")          ",[44,777,778],{"class":106},"# delete if present\n",[15,780,781,784,785,788,789,265,792,269],{},[19,782,783],{},"mkdir(parents=True, exist_ok=True)"," and ",[19,786,787],{},"unlink(missing_ok=True)"," handle the \"already\nexists \u002F doesn't exist\" cases without ",[19,790,791],{},"try",[19,793,794],{},"except",[10,796,798],{"id":797},"recap","Recap",[15,800,801,802,807,808,811,812,815,816,265,818,265,820,265,822,65,824,827,828,830,831,834,835,839,840,842,843,845,846,265,849,265,852,265,855,858,859,265,862,265,865,868,869,265,871,873],{},"Open files with ",[803,804,805],"strong",{},[19,806,32],{}," so they're closed automatically, and always pass\n",[19,809,810],{},"encoding=\"utf-8\"",". Know the ",[803,813,814],{},"modes"," (",[19,817,126],{},[19,819,130],{},[19,821,134],{},[19,823,138],{},[19,825,826],{},"+b","), remember ",[19,829,130],{}," truncates, and\n",[803,832,833],{},"iterate the file object"," to stream large files line by line. Prefer ",[803,836,837],{},[19,838,411],{}," over\n",[19,841,415],{},": join with ",[19,844,265],{},", inspect with ",[19,847,848],{},".name",[19,850,851],{},".stem",[19,853,854],{},".suffix",[19,856,857],{},".parent",", read and write\nwith ",[19,860,861],{},"read_text",[19,863,864],{},"write_text",[19,866,867],{},"read_bytes",", and find files with ",[19,870,658],{},[19,872,662],{},". It's the\nmodern, portable, readable way to handle the filesystem.",[875,876,877],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":40,"searchDepth":92,"depth":92,"links":879},[880,881,882,883,884,885,886,887],{"id":12,"depth":92,"text":13},{"id":25,"depth":92,"text":26},{"id":119,"depth":92,"text":120},{"id":248,"depth":92,"text":249},{"id":405,"depth":92,"text":406},{"id":528,"depth":92,"text":529},{"id":649,"depth":92,"text":650},{"id":797,"depth":92,"text":798},"How to work with files and paths in Python — opening files with context managers, read\u002Fwrite modes, text vs binary, and the modern pathlib API that replaces os.path string juggling.","medium","md","Python",{},"\u002Fblog\u002Fpython-files-pathlib-explained","\u002Fpython\u002Fstdlib\u002Ffiles-pathlib",{"title":5,"description":888},"blog\u002Fpython-files-pathlib-explained","Files, pathlib & os","Standard Library Essentials","stdlib","2026-06-19","uN33RqR6nNbTjRsHrFT9NZW2K17J9DzqQg9GJIOyAT0",1782244092830]