කූඩුවක ඇති නාමාවලියක් ආරක්ෂිතව නිර්මාණය කරන්නේ කෙසේද?


4263

ගොනුවක් ලිවීමට යන්නේද යන්න පරීක්ෂා කිරීමට වඩාත්ම අලංකාර ක්‍රමය කුමක්ද, නැතිනම් පයිතන් භාවිතයෙන් නාමාවලිය සාදන්න? මෙන්න මම උත්සාහ කළ දේ:

import os

file_path = "/my/directory/filename.txt"
directory = os.path.dirname(file_path)

try:
    os.stat(directory)
except:
    os.mkdir(directory)       

f = file(filename)

කෙසේ හෝ මට මග හැරුණි os.path.exists(ස්තූතියි කන්ජා, බ්ලෙයාර් සහ ඩග්ලස්). මට දැන් ඇත්තේ මෙයයි:

def ensure_dir(file_path):
    directory = os.path.dirname(file_path)
    if not os.path.exists(directory):
        os.makedirs(directory)

"විවෘත" සඳහා ධජයක් තිබේද, මෙය ස්වයංක්‍රීයව සිදු වේ ද?


27
පොදුවේ ගත් කල, ගොනු නාමයේ නාමාවලියක් නොමැති අවස්ථාවක ඔබට ගණන් දිය යුතුය. මගේ යන්ත්‍රයේ ඩිරම් නාමයෙන් ('foo.txt') '' ලබා දෙයි, එය නොපවතින අතර makedirs () අසමත් වීමට හේතු වේ.
බ්‍රයන් හෝකින්ස්

11
පයිතන් 2.7 හි os.path.mkdirනොපවතී. ඒ os.mkdir.
ඩ්‍රෙවිකෝ

6
මාර්ගය තිබේ නම් යමෙකුට එය නාමාවලියක්ද යන්න පරීක්ෂා කිරීම පමණක් නොව සාමාන්‍ය ගොනුවක් හෝ වෙනත් වස්තුවක් නොවේද (බොහෝ පිළිතුරු මෙය පරීක්ෂා කරයි) එය ලිවිය හැකිදැයි පරීක්ෂා කිරීමද අවශ්‍ය වේ (මෙය පරීක්ෂා කළ පිළිතුරක් මට හමු නොවීය)
ප්‍රාතිහාර්යය 17

9
ලිපිගොනු pos.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)
පෙළෙහි

Answers:


5208

පයිතන් ≥ 3.5 හි, භාවිතා කරන්න pathlib.Path.mkdir:

from pathlib import Path
Path("/my/directory").mkdir(parents=True, exist_ok=True)

පයිතන්ගේ පැරණි සංස්කරණ සඳහා, හොඳ ගුණාංග සහිත පිළිතුරු දෙකක් මම දකිමි, සෑම එකක්ම කුඩා අඩුපාඩුවක් ඇත, එබැවින් මම එය භාර ගනිමි:

උත්සාහ කරන්න os.path.exists, සහ os.makedirsනිර්මාණය සඳහා සලකා බලන්න .

import os
if not os.path.exists(directory):
    os.makedirs(directory)

අදහස් දැක්වීම්වල සහ වෙනත් තැන්වල සඳහන් කර ඇති පරිදි, තරඟ කොන්දේසියක් ඇත - os.path.existsසහ os.makedirsඇමතුම් අතර නාමාවලිය නිර්මාණය කර ඇත්නම් , ඒ os.makedirsසමඟ අසමත් වනු ඇත OSError. අවාසනාවකට මෙන්, බ්ලැන්කට් ඇල්ලීම OSErrorසහ ඉදිරියට යාම මෝඩකමක් නොවේ, මන්ද එය ප්‍රමාණවත් නොවන අවසර, සම්පූර්ණ තැටිය වැනි වෙනත් සාධක නිසා නාමාවලිය නිර්මාණය කිරීමට අපොහොසත් වනු ඇත.

එක් විකල්පයක් වනුයේ OSErrorකාවැද්දූ දෝෂ කේතය පරීක්ෂා කර බැලීමයි (බලන්න පයිතන්ගේ OSError වෙතින් තොරතුරු ලබා ගැනීමේ හරස් වේදිකා ක්‍රමයක් තිබේද ):

import os, errno

try:
    os.makedirs(directory)
except OSError as e:
    if e.errno != errno.EEXIST:
        raise

විකල්පයක් ලෙස, තත්පරයක් තිබිය හැකි os.path.existsනමුත්, පළමු චෙක්පතෙන් පසුව තවත් අයෙකු නාමාවලිය නිර්මාණය කර, දෙවන පරීක්‍ෂණයට පෙර එය ඉවත් කළා යැයි සිතමු - අප තවමත් රැවටිය හැකිය.

යෙදුම මත පදනම්ව, සමගාමී මෙහෙයුම් වල අන්තරාය ගොනු අවසර වැනි වෙනත් සාධක මගින් ඇති වන අන්තරායට වඩා වැඩි හෝ අඩු විය හැකිය. ක්‍රියාත්මක කිරීමක් තෝරා ගැනීමට පෙර සංවර්ධකයාට විශේෂිත යෙදුම සහ එහි අපේක්ෂිත පරිසරය ගැන වැඩි විස්තර දැනගත යුතුය.

පයිතන්ගේ නවීන අනුවාදයන් නිරාවරණය කිරීමෙන් FileExistsError(3.3 + දී) මෙම කේතය තරමක් දියුණු කරයි ...

try:
    os.makedirs("path/to/directory")
except FileExistsError:
    # directory already exists
    pass

... සහ (3.2+ දී) මූල පද තර්කයක් os.makedirsකැඳවීමටexist_ok ඉඩ දීමෙන් .

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.

5
ධාවන තත්වය හොඳ ලක්ෂ්‍යයකි, නමුත් stackoverflow.com/questions/273192/#273208 හි ප්‍රවේශය , නාමාවලිය නිර්මාණය කිරීමට අපොහොසත් වනු ඇත. ඡන්දය ප්‍රකාශ කිරීම ගැන නරකක් දැනෙන්න එපා - ඔබ පිළිතුරට කැමති නැත. ඡන්දය යනු එයයි.
බ්ලෙයාර් කොන්රාඩ්

27
Os.path.exists () නොමිලේ නොවන බව මතක තබා ගන්න. සාමාන්‍ය නඩුව නම් ඩිරෙක්ටරිය එහි තිබේ නම් එය එසේ නොවන අවස්ථාව ව්‍යතිරේකයක් ලෙස හැසිරවිය යුතුය. වෙනත් වචන වලින් කිවහොත්, ඔබේ ගොනුව විවෘත කිරීමට හා ලිවීමට උත්සාහ කරන්න, OSError ව්‍යතිරේකය අල්ලාගෙන, වැරදි මත පදනම්ව, ඔබේ makedir () කර නැවත උත්සාහ කරන්න හෝ නැවත මතු කරන්න. ඔබ දේශීය ක්‍රමයකින් ලිවීම ඔතා නොගන්නේ නම් මෙය කේතයේ අනුපිටපතක් නිර්මාණය කරයි.
ඇන්ඩෲ

22
os.path.existsTrueගොනුවක් සඳහා ද නැවත පැමිණේ . මෙය විසඳීම සඳහා මම පිළිතුරක් පළ කර ඇත්තෙමි.
Acumenus

13
මෙහි ඇති වෙනත් පිළිතුරු සඳහා විවරණකරුවන් සඳහන් කර ඇති පරිදි, පයිතන් 3.2 සිට, මාර්ගයේ පූර්ව පැවැත්ම හසුරුවන ආකාරය ආවරණය කිරීමට exists_okපරාමිතිය භාවිතා os.makedirs()කළ හැකිය.
බොබ්ල්

6
os.mkdirs()මාර්ග බෙදුම්කරුවෙකු අහම්බෙන් අතහැර දමා ඇත්නම්, වත්මන් ෆෝල්ඩරය බලාපොරොත්තු වූ පරිදි නොවේ නම්, මාර්ග මූලද්‍රව්‍යයක මාර්ග බෙදුම්කරු අඩංගු වේ නම් අනපේක්ෂිත ෆෝල්ඩර සෑදිය හැකිය. ඔබ os.mkdir()මෙම දෝෂ භාවිතා කරන්නේ නම් ව්‍යතිරේකයක් මතු වනු ඇත, ඒවායේ පැවැත්ම පිළිබඳව ඔබව දැනුවත් කරයි.
ඩ්‍රෙවිකෝ

1244

පයිතන් 3.5+:

import pathlib
pathlib.Path('/my/directory').mkdir(parents=True, exist_ok=True) 

pathlib.Path.mkdirඉහත භාවිතා කළ පරිදි පුනරාවර්තන ලෙස නාමාවලිය නිර්මාණය වන අතර නාමාවලිය දැනටමත් තිබේ නම් ව්‍යතිරේකයක් මතු නොකරයි. දෙමව්පියන් මැවීම ඔබට අවශ්‍ය නැතිනම් අවශ්‍ය නොවේ නම්, parentsතර්කය මඟ හරින්න .

පයිතන් 3.2+:

භාවිතා කිරීම pathlib:

ඔබට හැකි නම්, නම් කර ඇති වර්තමාන pathlibපසුපෙළ ස්ථාපනය කරන්න pathlib2. නම් කර ඇති පැරණි නොදන්නා පසුපෙළ ස්ථාපනය නොකරන්න pathlib. ඊළඟට, ඉහත පයිතන් 3.5+ කොටස වෙත යොමු වී එය භාවිතා කරන්න.

පයිතන් 3.4 භාවිතා කරන්නේ නම්, එය පැමිණියද pathlib, එය ප්‍රයෝජනවත් exist_okවිකල්පය මග හැරී ඇත. mkdirමෙම අතුරුදහන් වූ විකල්පය ඇතුළත් නව හා උසස් ක්‍රියාත්මක කිරීමක් බැක්පෝට් හි අරමුණයි .

භාවිතා කිරීම os:

import os
os.makedirs(path, exist_ok=True)

os.makedirsඉහත භාවිතා කළ පරිදි පුනරාවර්තන ලෙස නාමාවලිය නිර්මාණය වන අතර නාමාවලිය දැනටමත් තිබේ නම් ව්‍යතිරේකයක් මතු නොකරයි. එයට විකල්ප exist_okතර්කය ඇත්තේ පෙරනිමි අගය සහිත පයිතන් 3.2+ භාවිතා කරන්නේ නම් පමණි False. මෙම තර්කය පයිතන් 2.x හි 2.7 දක්වා නොපවතී. එනිසා, පයිතන් 2.7 මෙන් අතින් ව්‍යතිරේක හැසිරවීමේ අවශ්‍යතාවයක් නොමැත.

පයිතන් 2.7+:

භාවිතා කිරීම pathlib:

ඔබට හැකි නම්, නම් කර ඇති වර්තමාන pathlibපසුපෙළ ස්ථාපනය කරන්න pathlib2. නම් කර ඇති පැරණි නොදන්නා පසුපෙළ ස්ථාපනය නොකරන්න pathlib. ඊළඟට, ඉහත පයිතන් 3.5+ කොටස වෙත යොමු වී එය භාවිතා කරන්න.

භාවිතා කිරීම os:

import os
try: 
    os.makedirs(path)
except OSError:
    if not os.path.isdir(path):
        raise

බොළඳ විසඳුමක් මුලින්ම භාවිතා os.path.isdirකළ හැකි අතර os.makedirs, ඉහත විසඳුම මෙහෙයුම් දෙකේ අනුපිළිවෙල ආපසු හරවයි. එසේ කිරීමෙන්, නාමාවලිය නිර්මාණය කිරීමේ අනුපිටපත් උත්සාහයක් සමඟ පොදු තරඟ තත්වයක් ඇතිවීම වළක්වන අතර, නාමාවලි වලින් ලිපිගොනු අවලංගු කරයි.

ව්‍යතිරේකය ග්‍රහණය කර ගැනීම සහ භාවිතා errnoකිරීම සීමිත ප්‍රයෝජනයක් ඇති බව සලකන්න OSError: [Errno 17] File exists, එනම් errno.EEXISTලිපිගොනු සහ නාමාවලි සඳහාම මතු කර ඇත. නාමාවලිය තිබේදැයි පරීක්ෂා කිරීම වඩාත් විශ්වාසදායකය.

විකල්ප:

mkpathකැදැලි නාමාවලිය සාදයි, සහ නාමාවලිය දැනටමත් තිබේ නම් කිසිවක් නොකරයි. මෙය පයිතන් 2 සහ 3 යන දෙකින්ම ක්‍රියා කරයි.

import distutils.dir_util
distutils.dir_util.mkpath(path)

එක් බග් 10948 , මේ විකල්ප ක බැදීමද එය ලබා දී මාර්ගය සඳහා එක් වරක් පමණක් පිඹුරා ක්රියාවලිය අනුව ක්රියා කිරීමයි. වෙනත් වචන වලින් කිවහොත්, ඔබ එය ඩිරෙක්ටරියක් සෑදීමට භාවිතා කරන්නේ නම්, පයිතන් ඇතුළත හෝ පිටත සිට ඩිරෙක්ටරිය මකා දමන්න, ඉන්පසු එම ඩිරෙක්ටරිය mkpathනැවත ප්‍රතිනිර්මාණය කිරීමට නැවත mkpathභාවිතා කරන්න, කලින් ඩිරෙක්ටරිය නිර්මාණය කළ එහි අවලංගු හැඹිලි තොරතුරු නිහ ly ව භාවිතා කරනු ඇත, ඇත්ත වශයෙන්ම නැවත නාමාවලිය සාදන්න. ඊට වෙනස්ව, os.makedirsඑවැනි හැඹිලියක් මත රඳා නොසිටින්න. සමහර යෙදුම් සඳහා මෙම සීමාව හොඳ විය හැකිය.


නාමාවලි මාදිලිය සම්බන්ධයෙන් , කරුණාකර ඔබ ඒ ගැන සැලකිලිමත් වන්නේ නම් ප්‍රලේඛනය වෙත යොමු වන්න.


13
මට කිව හැකි තාක් දුරට මෙම පිළිතුර සෑම විශේෂ අවස්ථාවක්ම ආවරණය කරයි. සෑම විටම පාහේ නාමාවලිය පවතිනු ඇතැයි මම අපේක්ෂා කරන නමුත් මට ඒ ආකාරයෙන් ව්‍යතිරේකය වළක්වා ගත හැකි බැවින් මම මෙය "එසේ නොවේ නම් os.path.isdir ()" ඔතා තැබීමට අදහස් කරමි.
චාල්ස් එල්.

5
Har චාර්ලස් එල්. ඔබේ හේතුව කාර්ය සාධනය නම්, ව්‍යතිරේකය චෙක්පතෙහි තැටියට වඩා ලාභදායී වේ.
jpmc26

1
pm jpmc26 නමුත් OSError විසි කිරීමට පමණක් පරීක්ෂා කරන විට makedirs අතිරේක stat, umask, lstat කරයි.
kwarunek

4
විභව එෆ්එස් රේස් කොන්ඩයක් හඳුන්වා දෙන බැවින් මෙය වැරදි පිළිතුරකි. ආරොන් හෝල් වෙතින් පිළිතුර බලන්න.
sleepycal

4
sleepsleepycal පවසා ඇති පරිදි, මෙය පිළිගත් පිළිතුරට සමාන ධාවන තත්වයකින් පෙළේ. දෝෂය මතු කිරීම සහ os.path.isdirවෙනත් අයෙකු පරීක්ෂා කිරීම අතර ෆෝල්ඩරය මකා දැමුවහොත් , ඔබ ෆෝල්ඩරය පවතින වැරදි, යල් පැන ගිය සහ ව්‍යාකූල දෝෂයක් මතු කරයි.
farmir

604

හැරෙන්නට උත්සාහ කිරීම සහ වැරදි දෝෂ කේතය වැරදි මොඩියුලයෙන් ධාවන තත්වයෙන් ඉවත් වන අතර එය හරස් වේදිකාවකි:

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise

වෙනත් වචන වලින් කිවහොත්, අපි නාමාවලි නිර්මාණය කිරීමට උත්සාහ කරමු, නමුත් ඒවා දැනටමත් තිබේ නම් අපි දෝෂය නොසලකා හරිමු. අනෙක් අතට, වෙනත් ඕනෑම දෝෂයක් වාර්තා වේ. උදාහරණයක් ලෙස, ඔබ කලින් හිස් තීරුවෙහි 'a' නිර්මාණය හා එය සියලු අවසර ඉවත් නම්, ඔබ වනු ඇත OSErrorසමග මතු errno.EACCES(අවසරය දෝෂයක් 13 ප්රතික්ෂේප).


24
පිළිගත් පිළිතුර ඇත්ත වශයෙන්ම භයානක වන්නේ එයට ධාවන තත්වයක් ඇති බැවිනි. එය වඩාත් සරල ය, එබැවින් ඔබ ධාවන තත්ත්වය ගැන නොදන්නේ නම් හෝ එය ඔබට අදාළ නොවනු ඇතැයි සිතන්නේ නම්, එය ඔබේ පළමු තේරීම වේ.
හයිකි ටොයිවොනන්

15
ව්‍යතිරේකය ඉහළ නැංවීම exception.errno != errno.EEXISTමාර්ගය පවතින විට නොදැනුවත්වම නොසලකා හරිනු ඇති නමුත් එය ගොනුවක් වැනි නාමාවලි නොවන වස්තුවකි. මාර්ගය නාමාවලි නොවන වස්තුවක් නම් ව්‍යතිරේකය ඉතා මැනවින් මතු කළ යුතුය.
Acumenus

178
ඉහත කේතය සමාන බව සලකන්නos.makedirs(path,exist_ok=True)
නවීන්

58
Av නවින් exist_okපරාමිතිය පයිතන් 3.2 හි හඳුන්වා දෙන ලදී. එය පයිතන් 2.x හි නොමැත. මම එය මගේ පිළිතුරට ඇතුළත් කරමි.
Acumenus

26
EHeikkiToivonen තාක්‍ෂණිකව කිවහොත්, වෙනත් වැඩසටහනක් ඔබේ වැඩසටහන එකවරම නාමාවලි සහ ලිපිගොනු වෙනස් කරන්නේ නම්, ඔබේ මුළු වැඩසටහනම යෝධ ධාවන තත්වයකි. කේතය නිර්මාණය කිරීමෙන් පසුව සහ ඇත්ත වශයෙන්ම ලිපිගොනු දැමීමට පෙර වෙනත් වැඩසටහනක් මෙම නාමාවලිය මකා දැමීමෙන් වළක්වා ගත යුත්තේ කුමක් ද?
jpmc26

102

මම පෞද්ගලිකව නිර්දේශ කරන්නේ ඔබ os.path.isdir()ඒ වෙනුවට පරීක්ෂා කිරීමට භාවිතා කරන ලෙසයි os.path.exists().

>>> os.path.exists('/tmp/dirname')
True
>>> os.path.exists('/tmp/dirname/filename.etc')
True
>>> os.path.isdir('/tmp/dirname/filename.etc')
False
>>> os.path.isdir('/tmp/fakedirname')
False

ඔබට තිබේ නම්:

>>> dir = raw_input(":: ")

සහ මෝඩ පරිශීලක ආදානය:

:: /tmp/dirname/filename.etc

... ඔයා නම් බහලුම සමග අවසන් යන්නේ filename.etcඔබ එම තර්කය සමත් විට os.makedirs()ඔබ පරීක්ෂා සමග නම් os.path.exists().


8
ඔබ 'isdir' පමණක් භාවිතා කරන්නේ නම්, ඔබ ඩිරෙක්ටරිය නිර්මාණය කිරීමට උත්සාහ කරන විටත්, එකම නමක් ඇති ගොනුවක් දැනටමත් පවතින විටත් ඔබට තවමත් ගැටළුවක් ඇති නොවේද?
MrWonderful

3
RMrWonderful දැනට පවතින ගොනුවක් හරහා නාමාවලියක් නිර්මාණය කිරීමේදී ඇති වන ව්‍යතිරේකය, ඇමතුම වෙත ගැටළුව නිවැරදිව පිළිබිඹු කරයි.
ඩේමියන් යෙරික්

79

පරීක්ෂා කරන්න os.makedirs: (එය සම්පූර්ණ මාර්ගය පවතින බව සහතික කරයි.)
නාමාවලිය පැවතිය හැකි බව හැසිරවීමට, අල්ලා ගන්න OSError. (නම් exist_okවේ False) පෙරනිමි (ක OSErrorඉලක්ක ගත බහලුම දැනටමත් පවතී නම්, මතු කර ඇත.)

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass

19
උත්සාහය / හැර, ඔබ ඩිරෙක්ටරිය නිර්මාණය කිරීමේදී දෝෂ වසං කරනු ඇත, ඩිරෙක්ටරිය නොපවතින නමුත් යම් හේතුවක් නිසා ඔබට එය කළ නොහැක
බ්ලෙයාර් කොන්රාඩ්

3
OSErrorමාර්ගය දැනට පවතින ගොනුවක් හෝ නාමාවලියක් නම් මෙහි මතු කරනු ඇත. මෙය විසඳීම සඳහා මම පිළිතුරක් පළ කර ඇත්තෙමි.
Acumenus

4
මේක බාගෙට. OSErrorඑය නොසලකා හැරීමට තීරණය කිරීමට පෙර උප-දෝෂ තත්ත්වය පරීක්ෂා කිරීම අවශ්‍ය වේ . Stackoverflow.com/a/5032238/763269 බලන්න .
ක්‍රිස් ජොන්සන්

71

පයිතන් 3.5 සිට ආරම්භ pathlib.Path.mkdirවන exist_okධජයක් ඇත:

from pathlib import Path
path = Path('/my/directory/filename.txt')
path.parent.mkdir(parents=True, exist_ok=True) 
# path.parent ~ os.path.dirname(path)

මෙය පුනරාවර්තන ලෙස නාමාවලිය නිර්මාණය කරන අතර නාමාවලිය දැනටමත් තිබේ නම් ව්‍යතිරේකයක් මතු නොකරයි.

( පයිතන් 3.2 සිට ආරම්භ os.makedirsවන exist_okධජයක් ලැබුණාක් මෙන් os.makedirs(path, exist_ok=True))


46

මෙම තත්වයේ විශේෂතා පිළිබඳ තීක්ෂ්ණ බුද්ධිය

ඔබ කිසියම් ගොනුවක් එක්තරා මාර්ගයකට ලබා දෙන අතර ඔබ ඩිරෙක්ටරිය ගොනු මාර්ගයෙන් අදින්න. ඔබට ඩිරෙක්ටරිය ඇති බවට තහවුරු කරගත් පසු, කියවීම සඳහා ගොනුවක් විවෘත කිරීමට ඔබ උත්සාහ කරයි. මෙම කේතය පිළිබඳව අදහස් දැක්වීමට:

filename = "/my/directory/filename.txt"
dir = os.path.dirname(filename)

බිල්ඩින් ශ්‍රිතය නැවත ලිවීමෙන් වැළකී සිටීමට අපට අවශ්‍යය dir. එසේම, filepathහෝ සමහර fullfilepathවිට වඩා හොඳ අර්ථකථන නාමයක් වන filenameබැවින් මෙය වඩා හොඳින් ලිවිය හැකිය:

import os
filepath = '/my/directory/filename.txt'
directory = os.path.dirname(filepath)

ඔබේ අවසාන ඉලක්කය වන්නේ මෙම ගොනුව විවෘත කිරීමයි, ඔබ මුලින් සඳහන් කරන්නේ ලිවීම සඳහා ය, නමුත් ඔබ මූලිකවම මෙම ඉලක්කයට (ඔබේ කේතය මත පදනම්ව) ළඟා වේ, එය කියවීම සඳහා ගොනුව විවෘත කරයි :

if not os.path.exists(directory):
    os.makedirs(directory)
f = file(filename)

කියවීම සඳහා විවෘත කිරීම උපකල්පනය කිරීම

ඔබ එහි සිටිමින් කියවීමට හැකි යැයි අපේක්ෂා කරන ගොනුවක් සඳහා නාමාවලියක් සාදන්නේ ඇයි?

ගොනුව විවෘත කිරීමට උත්සාහ කරන්න.

with open(filepath) as my_file:
    do_stuff(my_file)

නාමාවලිය හෝ ගොනුව නොමැති නම්, ඔබට IOErrorසම්බන්ධිත දෝෂ අංකයක් errno.ENOENTලැබෙනු ඇත : ඔබේ වේදිකාව නොසලකා නිවැරදි දෝෂ අංකයට යොමු වේ. ඔබට අවශ්‍ය නම් එය අල්ලා ගත හැකිය, උදාහරණයක් ලෙස:

import errno
try:
    with open(filepath) as my_file:
        do_stuff(my_file)
except IOError as error:
    if error.errno == errno.ENOENT:
        print 'ignoring error because directory or file is not there'
    else:
        raise

අපි ලිවීමට විවෘත යැයි සිතමු

මෙය ඔබට අවශ්‍ය දේ විය හැකිය .

මෙම අවස්ථාවේ දී, අපි බොහෝ විට කිසිදු ධාවන තත්වයකට මුහුණ නොදේ. එබැවින් ඔබ සිටි ආකාරයටම කරන්න, නමුත් ලිවීම සඳහා, ඔබ wමාදිලිය සමඟ විවෘත කළ යුතු බව සලකන්න (හෝ aඑකතු කිරීමට). ලිපිගොනු විවෘත කිරීම සඳහා සන්දර්භය කළමනාකරු භාවිතා කිරීම පයිතන් හොඳම පුරුද්දකි.

import os
if not os.path.exists(directory):
    os.makedirs(directory)
with open(filepath, 'w') as my_file:
    do_stuff(my_file)

කෙසේ වෙතත්, අපට කියන්න පයිතන් ක්‍රියාවලි කිහිපයක් ඇති අතර ඒවායේ දත්ත සියල්ලම එකම ඩිරෙක්ටරියට දැමීමට උත්සාහ කරයි. එවිට නාමාවලිය නිර්මාණය කිරීම සම්බන්ධයෙන් අපට මතභේද ඇති විය හැකිය. එවැනි අවස්ථාවකදී makedirsඇමතුම උත්සාහ කිරීම හැර වාරණයකින් ඔතා තැබීම වඩාත් සුදුසුය .

import os
import errno
if not os.path.exists(directory):
    try:
        os.makedirs(directory)
    except OSError as error:
        if error.errno != errno.EEXIST:
            raise
with open(filepath, 'w') as my_file:
    do_stuff(my_file)

34

os.path.existsශ්‍රිතය උත්සාහ කරන්න

if not os.path.exists(dir):
    os.mkdir(dir)

3
මම ප්‍රශ්නය ගැන අදහස් දැක්වීමට ගිය නමුත් අපි අදහස් කළේ os.mkdir ද? මගේ පයිතන් (2.5.2) ට os.path.mkdir නොමැත ....
බ්ලෙයාර් කොන්රාඩ්

1
os.path.mkdir()ක්රමයක් නොමැත . os.path මොඩියුලය මාර්ග නාමයන්හි ප්‍රයෝජනවත් කාර්යයන් කිහිපයක් ක්‍රියාත්මක කරයි .
සර්ජ් එස්.

31

මම පහත සඳහන් දෑ පහත දැමුවෙමි. එය මුළුමනින්ම මෝඩකමක් නොවේ.

import os

dirname = 'create/me'

try:
    os.makedirs(dirname)
except OSError:
    if os.path.exists(dirname):
        # We are nearly safe
        pass
    else:
        # There was an error on creation, so make sure we know about it
        raise

දැන් මා පවසන පරිදි, මෙය සැබවින්ම මෝඩකමක් නොවේ, මන්ද අපට නාමාවලිය නිර්මාණය කිරීමට අපොහොසත් වීමේ හැකියාව සහ එම කාලය තුළ එය නිර්මාණය කිරීමේ තවත් ක්‍රියාවලියක් ඇත.



ගැටළු දෙකක්: (1) පරීක්ෂා කිරීමට පෙර ඔබ OSError හි උප දෝෂ තත්ත්වය පරීක්ෂා කළ යුතුය os.path.exists- stackoverflow.com/a/5032238/763269 බලන්න, සහ (2) සාර්ථකත්වය os.path.existsයනු නාමාවලිය පවතින බව නොවේ, මාර්ගය පමණක් පවතී - ගොනුවක්, හෝ සිම්ලින්ක් හෝ වෙනත් ගොනු පද්ධති වස්තුවක් විය හැකිය.
ක්‍රිස් ජොන්සන්

24

නාමාවලියක් තිබේදැයි පරීක්ෂා කර අවශ්‍ය නම් එය සාදන්න?

මෙයට answer ජු පිළිතුර නම්, වෙනත් පරිශීලකයින් හෝ ක්‍රියාවලි ඔබේ නාමාවලිය සමඟ අවුල් වනු ඇතැයි ඔබ අපේක්ෂා නොකරන සරල තත්වයක් උපකල්පනය කිරීම:

if not os.path.exists(d):
    os.makedirs(d)

හෝ නාමාවලිය සෑදීම ධාවන තත්වයන්ට යටත් වේ නම් (එනම් මාර්ගය තිබේදැයි පරීක්ෂා කිරීමෙන් පසුව, වෙනත් දෙයක් දැනටමත් එය සාදා ඇත) මෙය කරන්න:

import errno
try:
    os.makedirs(d)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise

තාවකාලික නාමාවලි භාවිතා කරමින් සම්පත් විවාදාත්මක ගැටළුව මඟ හැරීම සමහර විට ඊටත් වඩා හොඳ ප්‍රවේශයකි tempfile.

import tempfile

d = tempfile.mkdtemp()

සබැඳි ලේඛනයේ අත්‍යවශ්‍ය දෑ මෙන්න:

mkdtemp(suffix='', prefix='tmp', dir=None)
    User-callable function to create and return a unique temporary
    directory.  The return value is the pathname of the directory.

    The directory is readable, writable, and searchable only by the
    creating user.

    Caller is responsible for deleting the directory when done with it.

පයිතන් 3.5 හි නව: pathlib.Pathසමඟexist_ok

නව Pathවස්තුවක් ඇත (3.4 වන විට) කෙනෙකුට මාර්ග සමඟ භාවිතා කිරීමට අවශ්‍ය ක්‍රම රාශියක් ඇත - ඉන් එකක් mkdir.

.

පළමුව අදාළ ආනයන:

from pathlib import Path
import tempfile

අපට os.path.joinදැන් ගනුදෙනු කිරීමට අවශ්‍ය නැත - මාර්ග කොටස් සමඟ සම්බන්ධ වන්න /:

directory = Path(tempfile.gettempdir()) / 'sodata'

එවිට මම නාමාවලිය පවතින බව සහතිකවම සහතික කරමි - exist_okතර්කය පයිතන් 3.5 හි දැක්වේ:

directory.mkdir(exist_ok=True)

ප්‍රලේඛනයේ අදාළ කොටස මෙන්න :

exist_okසත්‍ය නම් , FileExistsErrorව්‍යතිරේකයන් නොසලකා හරිනු ඇත ( POSIX mkdir -pවිධානයට සමාන හැසිරීම ), නමුත් අවසාන මාර්ග සංරචකය දැනට පවතින නාමාවලි නොවන ගොනුවක් නොවේ නම් පමණි.

මෙන්න ස්ක්‍රිප්ට් එකෙන් ටිකක් වැඩියි - මගේ කාරණයේදී, මම ධාවන තත්වයකට යටත් නොවෙමි, මට ඇත්තේ එක් ක්‍රියාවලියක් පමණි, එමඟින් ඩිරෙක්ටරිය (හෝ ලිපිගොනු අඩංගු) තිබිය යුතු යැයි අපේක්ෂා කරන අතර ඉවත් කිරීමට උත්සාහ කරන කිසිවක් මා සතුව නොමැත නාමාවලිය.

todays_file = directory / str(datetime.datetime.utcnow().date())
if todays_file.exists():
    logger.info("todays_file exists: " + str(todays_file))
    df = pd.read_json(str(todays_file))

Pathමාර්ග භාවිතා කිරීමට strබලාපොරොත්තු වන වෙනත් ඒපීඅයි වලට පෙර වස්තු බල strකළ යුතුය.

වියුක්ත පාදක පන්තියේ අවස්ථා පිළිගැනීමට සමහර විට පැන්ඩා යාවත්කාලීන කළ යුතුය os.PathLike.


20

පයිතන් 3.4 හි ඔබට නවතම pathlibමොඩියුලය භාවිතා කළ හැකිය :

from pathlib import Path
path = Path("/my/directory/filename.txt")
try:
    if not path.parent.exists():
        path.parent.mkdir(parents=True)
except OSError:
    # handle error; you can also catch specific errors like
    # FileExistsError and so on.

@JanuszSkonieczny pypi.python.org/pypi/pathlib2 යනු නවතම පසුපෙළයි . වැඩිමහල් තැනැත්තා නොදැන සිටියි.
Acumenus

එය කියවීමේ පළමු පේළියේ සඳහන් පරිදි; පී. නමුත් මෙහි ඇති පිළිතුර සඳහා පැරණි පසුපෙළ තවමත් වලංගු වේ. නම් කිරීමේ හිසරදය නැත. නව පරිශීලකයින් සඳහා ඇයි සහ කවදාද pathlibසහ කොතැනද යන්න පැහැදිලි කිරීමට අවශ්‍ය නැත pathlib2, මෙහි ඇති වාසි
ක්ෂය වීම හඳුනා ගනී

13

මෙම අදාළ Python ප්රලේඛනය භාවිතා කිරීම යෝජනා EAFP කේතනය ශෛලිය (අවසරය වඩා සමාව ඉල්ලන්න පහසු) . මෙයින් අදහස් කරන්නේ කේතය බවයි

try:
    os.makedirs(path)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise
    else:
        print "\nBE CAREFUL! Directory %s already exists." % path

විකල්පයට වඩා හොඳයි

if not os.path.exists(path):
    os.makedirs(path)
else:
    print "\nBE CAREFUL! Directory %s already exists." % path

ප්‍රලේඛනය මෙය හරියටම යෝජනා කරන්නේ මෙම ප්‍රශ්නයේ සාකච්ඡා කර ඇති ධාවන තත්වය නිසාය. මීට අමතරව, අනෙක් අය මෙහි සඳහන් කර ඇති පරිදි, මෙහෙයුම් පද්ධතිය මෙන් දෙගුණයක් වෙනුවට එක් වරක් විමසීමේ කාර්ය සාධන වාසියක් ඇත. අවසාන වශයෙන්, සමහර අවස්ථාවල දෙවන කේතයට පක්ෂව ඉදිරිපත් කළ හැකි තර්කය - යෙදුම ක්‍රියාත්මක වන පරිසරය සංවර්ධකයා දන්නා විට - එය ඉදිරිපත් කළ හැක්කේ වැඩසටහන සඳහා පුද්ගලික පරිසරයක් සැකසූ විශේෂ අවස්ථාවකදී පමණි. (සහ එකම වැඩසටහනේ වෙනත් අවස්ථා).

එවැනි අවස්ථාවකදී පවා මෙය නරක පුරුද්දක් වන අතර එය දිගු කලක් තිස්සේ නිදොස් කිරීමකට තුඩු දිය හැකිය. නිදසුනක් ලෙස, නාමාවලියක් සඳහා අප විසින් අවසර ලබා දී තිබීම අපගේ අරමුණු සඳහා සුදුසු පරිදි සකසා ඇති බව හැඟීමෙන් අපව අත් නොහැරිය යුතුය. මව් නාමාවලිය වෙනත් අවසරයන් සමඟ සවි කළ හැකිය. පොදුවේ ගත් කල, වැඩසටහනක් සෑම විටම නිවැරදිව ක්‍රියා කළ යුතු අතර ක්‍රමලේඛකයා එක් නිශ්චිත පරිසරයක් අපේක්ෂා නොකළ යුතුය.


12

දී Python3 , os.makedirsසැකසීම සඳහා සහාය exist_ok. පෙරනිමි සැකසුම නම් False, එයින් අදහස් කරන්නේ OSErrorඉලක්ක නාමාවලිය දැනටමත් තිබේ නම් එය මතු කරනු ඇති බවයි. සැකසීමෙන් exist_okකිරීමට True, OSError(බහලුම පවතී) එය නොසලකා හරිනු ලැබේ සහ බහලුම නිර්මාණය කළ නොහැකි වනු ඇත.

os.makedirs(path,exist_ok=True)

දී Python2 , os.makedirsසැකසීම සඳහා පහසුකම් සපයන්නේ නැත exist_ok. හයිකි-ටොයිවොනන්ගේ පිළිතුරෙන් ඔබට ප්‍රවේශය භාවිතා කළ හැකිය :

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise

11

එක් ලයිනර් විසඳුමක් සඳහා, ඔබට මෙය භාවිතා කළ හැකිය IPython.utils.path.ensure_dir_exists():

from IPython.utils.path import ensure_dir_exists
ensure_dir_exists(dir)

සිට ප්රලේඛනය : නාමාවලියක් පවතින බව තහවුරු කර ගන්න. එය නොපවතී නම්, වෙනත් ක්‍රියාවලියක් එයම කරන්නේ නම් එය නිර්මාණය කර ධාවන තත්වයෙන් ආරක්ෂා වීමට උත්සාහ කරන්න.


නව IPython ප්‍රලේඛනය මෙහි ඇත.
jkdev

3
මෙම IPythonමොඩියුලය පරම සහභාගි වීමට සහතික කර නැත. එය මගේ මැක්හි ස්වදේශීයව පවතී, නමුත් මගේ ලයිනක්ස් පයිතන් ස්ථාපනය කිරීම් කිසිවක් නොවේ. මූලික වශයෙන්, එය පයිතන් මොඩියුල දර්ශකයේ ලැයිස්තුගත කර ඇති මොඩියුලවලින් එකක් නොවේ .
Acumenus

1
ෂුවර්. පැකේජය ස්ථාපනය කිරීම සඳහා, සුපුරුදු පරිදි ධාවනය pip install ipythonකරන්න හෝ ඔබේ අවශ්‍යතා මත යැපීම ඇතුළත් කරන්න . Txt හෝ pom.xml . ප්‍රලේඛනය: ipython.org/install.html
tashuhka

9

ඔයාට පාවිච්චි කරන්න පුළුවන් mkpath

# Create a directory and any missing ancestor directories. 
# If the directory already exists, do nothing.

from distutils.dir_util import mkpath
mkpath("test")    

එය මුතුන් මිත්තන්ගේ නාමාවලි ද නිර්මාණය කරන බව සලකන්න.

එය පයිතන් 2 සහ 3 සඳහා ක්‍රියා කරයි.


2
distutils.dir_utildistutil public API හි කොටසක් නොවන අතර බහු නූල් සහිත පරිසරවල ගැටළු ඇත: bugs.python.org/issue10948
Pod

1
ඔව්. දෝෂයේ පළමු පණිවුඩයේ සඳහන් කර ඇති පරිදි ගැටළුව distutils.dir_util.mkpathවන්නේ ඔබ ඩිරෙක්ටරියක් නිර්මාණය කරන්නේ නම්, එය පයිතන් ඇතුළත හෝ පිටත සිට මකා දමා mkpathනැවත mkpathභාවිතා කරන්න, කලින් ඩිරෙක්ටරිය නිර්මාණය කළ එහි අවලංගු හැඹිලි තොරතුරු භාවිතා කරනු ඇත. නැවත නාමාවලිය නැවත සාදන්න එපා. ඊට වෙනස්ව, os.makedirsඑවැනි හැඹිලියක් මත රඳා නොසිටින්න.
Acumenus

8

මම භාවිතා කරන්නේ os.path.exists(), මෙන්න පයිතන් 3 ස්ක්‍රිප්ටයක් වන අතර එය නාමාවලියක් තිබේදැයි පරීක්ෂා කිරීමට, එය නොපවතී නම් එකක් නිර්මාණය කිරීමට සහ එය තිබේ නම් එය මකා දැමීමට (අවශ්‍ය නම්) භාවිතා කළ හැකිය.

එය නාමාවලිය ආදානය කිරීමට පරිශීලකයින්ගෙන් ඉල්ලා සිටින අතර පහසුවෙන් වෙනස් කළ හැකිය.


6

ඔබට os.listdirමේ සඳහා භාවිතා කළ හැකිය :

import os
if 'dirName' in os.listdir('parentFolderPath')
    print('Directory Exists')

මෙය ප්‍රශ්නයට පිළිතුරු සපයන්නේ නැත
ජෝර්ජි

6

මෙම Q / A මට හමු වූ අතර, මට ලැබෙමින් තිබූ සමහර අසාර්ථකත්වයන් සහ දෝෂයන් නිසා මම මුලින් ව්‍යාකූල විය. මම වැඩ කරන්නේ පයිතන් 3 (v.3.5 ඇනකොන්ඩා අථත්‍ය පරිසරයක ආරුක්කු ලිනක්ස් x86_64 පද්ධතියක).

මෙම නාමාවලි ව්‍යුහය සලකා බලන්න:

└── output/         ## dir
   ├── corpus       ## file
   ├── corpus2/     ## dir
   └── subdir/      ## dir

මෙන්න මගේ අත්හදා බැලීම් / සටහන්, එය කරුණු පැහැදිලි කරයි:

# ----------------------------------------------------------------------------
# [1] /programming/273192/how-can-i-create-a-directory-if-it-does-not-exist

import pathlib

""" Notes:
        1.  Include a trailing slash at the end of the directory path
            ("Method 1," below).
        2.  If a subdirectory in your intended path matches an existing file
            with same name, you will get the following error:
            "NotADirectoryError: [Errno 20] Not a directory:" ...
"""
# Uncomment and try each of these "out_dir" paths, singly:

# ----------------------------------------------------------------------------
# METHOD 1:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but no file created (os.makedirs creates dir, not files!  ;-)
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# [2] https://docs.python.org/3/library/os.html#os.makedirs

# Uncomment these to run "Method 1":

#directory = os.path.dirname(out_dir)
#os.makedirs(directory, mode=0o777, exist_ok=True)

# ----------------------------------------------------------------------------
# METHOD 2:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## works
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## works
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but creates a .../doc.txt./ dir
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# Uncomment these to run "Method 2":

#import os, errno
#try:
#       os.makedirs(out_dir)
#except OSError as e:
#       if e.errno != errno.EEXIST:
#               raise
# ----------------------------------------------------------------------------

නිගමනය: මගේ මතය අනුව, "ක්රමය 2" වඩාත් ශක්තිමත් ය.

[1] නාමාවලියක් නොමැති නම් එය නිර්මාණය කරන්නේ කෙසේද?

[2] https://docs.python.org/3/library/os.html#os.makedirs




5

විකල්පයක් mkdirසහිත විධාන සඳහා සහය දක්වන යන්ත්‍රයක් මත ධාවනය වන්නේ නම් උපප්‍රොසෙස් මොඩියුලය භාවිතා නොකරන්නේ ඇයි -p? පයිතන් 2.7 සහ පයිතන් 3.6 මත ක්‍රියා කරයි

from subprocess import call
call(['mkdir', '-p', 'path1/path2/path3'])

බොහෝ පද්ධති වල උපක්‍රමය කළ යුතුය.

අතේ ගෙන යා හැකි වැදගත්කමක් නැති අවස්ථාවන්හිදී (උදා: ඩොකර් භාවිතා කිරීම) විසඳුම පිරිසිදු පේළි 2 කි. නාමාවලි තිබේද නැද්ද යන්න පරීක්ෂා කිරීමට ඔබට තර්කනය එකතු කිරීමට අවශ්‍ය නැත. අවසාන වශයෙන්, කිසිදු අතුරු ආබාධයකින් තොරව නැවත ධාවනය කිරීම ආරක්ෂිත වේ

ඔබට දෝෂ හැසිරවීම අවශ්‍ය නම්:

from subprocess import check_call
try:
    check_call(['mkdir', '-p', 'path1/path2/path3'])
except:
    handle...

4

ඔබ පහත සඳහන් කරුණු සලකා බලන්නේ නම්:

os.path.isdir('/tmp/dirname')

ඩිරෙක්ටරියක් (මාර්ගයක්) පවතින අතර එය නාමාවලියකි. ඉතින් මට නම් මේ විදියට මට අවශ්‍ය දේ කරනවා. එබැවින් එය ෆෝල්ඩරය (ගොනුවක් නොවේ) සහ පවතින බව මට සහතික කළ හැකිය.


නාමාවලියක් සෑදීමේ ප්‍රශ්නයකට මෙය පිළිතුරු දෙන්නේ කෙසේද ?
ජෝර්ජි

3

create_dir()ඔබේ වැඩසටහනේ / ව්‍යාපෘතියේ පිවිසුම් ස්ථානයේ ශ්‍රිතය අමතන්න .

import os

def create_dir(directory):
    if not os.path.exists(directory):
        print('Creating Directory '+directory)
        os.makedirs(directory)

create_dir('Project directory')

3

නාමාවලිය නිර්මාණය කිරීමට පෙර ඔබ සම්පූර්ණ මාර්ගය සැකසිය යුතුය:

import os,sys,inspect
import pathlib

currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
your_folder = currentdir + "/" + "your_folder"

if not os.path.exists(your_folder):
   pathlib.Path(your_folder).mkdir(parents=True, exist_ok=True)

මෙය මා වෙනුවෙන් ක්‍රියාත්මක වන අතර එය ඔබටත් ප්‍රයෝජනවත් වනු ඇත


1
import os
if os.path.isfile(filename):
    print "file exists"
else:
    "Your code here"

ඔබේ කේතය මෙහි (ස්පර්ශ) විධානය භාවිතා කරන්න

මෙමඟින් ගොනුව තිබේදැයි පරීක්ෂා කරනුයේ එය නොමැති නම් එය නිර්මාණය කරයි.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.