标签归档:operating-system

何时使用os.name,sys.platform或platform.system?

问题:何时使用os.name,sys.platform或platform.system?

据我所知,Python有3种方法来找出运行什么操作系统:

  1. os.name
  2. sys.platform
  3. platform.system()

知道此信息对于有条件导入或使用不同平台之间的功能(例如,time.clock()在Windows和time.time()UNIX上)通常很有用。

我的问题是,为什么要使用3种不同的方法?什么时候应该使用一种方法而不是另一种方法?哪种方法是“最佳”的(最好是面向未来的,或者最不可能偶然排除程序可以实际运行的特定系统)?

好像sys.platform是更具体的比os.name,让您区分win32来自cygwin(而不是只nt),并linux2darwin(而不是只posix)。但是,如果是这样,那sys.platform和之间的区别platform.system()呢?

例如,这更好:

import sys
if sys.platform == 'linux2':
    # Do Linux-specific stuff

或这个?:

import platform
if platform.system() == 'Linux':
    # Do Linux-specific stuff

现在,我将继续坚持sys.platform下去,因此这个问题并不是特别紧迫,但我将非常感谢您对此进行的澄清。

As far as I know, Python has 3 ways of finding out what operating system is running on:

  1. os.name
  2. sys.platform
  3. platform.system()

Knowing this information is often useful in conditional imports, or using functionality that differs between platforms (e.g. time.clock() on Windows v.s. time.time() on UNIX).

My question is, why 3 different ways of doing this? When should one way be used and not another? Which way is the ‘best’ (most future-proof or least likely to accidentally exclude a particular system which your program can actually run on)?

It seems like sys.platform is more specific than os.name, allowing you to distinguish win32 from cygwin (as opposed to just nt), and linux2 from darwin (as opposed to just posix). But if that’s so, that what about the difference between sys.platform and platform.system()?

For example, which is better, this:

import sys
if sys.platform == 'linux2':
    # Do Linux-specific stuff

or this? :

import platform
if platform.system() == 'Linux':
    # Do Linux-specific stuff

For now I’ll be sticking to sys.platform, so this question isn’t particularly urgent, but I would be very grateful for some clarification regarding this.


回答 0

深入研究源代码。

的输出sys.platformos.name在编译时被确定。platform.system()确定运行时的系统类型。

  • sys.platform 在构建配置期间被指定为编译器定义。
  • os.name检查是否某些操作系统特定模块可供选择(例如posixnt,…)
  • platform.system()实际运行uname以及可能在运行时确定系统类型的其他几个功能。

我的建议:

  • 使用os.name来检查它是否是一个POSIX兼容的系统。
  • 使用sys.platform来检查它是否是一个linux,cygwin的,达尔文,atheos等。
  • 使用platform.system(),如果你不相信的其他来源。

Dived a bit into the source code.

The output of sys.platform and os.name are determined at compile time. platform.system() determines the system type at run time.

  • sys.platform is specified as a compiler define during the build configuration.
  • os.name checks whether certain os specific modules are available (e.g. posix, nt, …)
  • platform.system() actually runs uname and potentially several other functions to determine the system type at run time.

My suggestion:

  • Use os.name to check whether it’s a posix-compliant system.
  • Use sys.platform to check whether it’s a linux, cygwin, darwin, atheos, etc.
  • Use platform.system() if you don’t believe the other sources.

回答 1

有一线之隔差platform.system()sys.platform,有趣的大多数情况下 platform.system()退化为sys.platform

这是消息人士Python2.7\Lib\Platform.py\system说的

def system():

    """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.

        An empty string is returned if the value cannot be determined.

    """
    return uname()[0]

def uname():
    # Get some infos from the builtin os.uname API...
    try:
        system,node,release,version,machine = os.uname()
    except AttributeError:
        no_os_uname = 1

    if no_os_uname or not filter(None, (system, node, release, version, machine)):
        # Hmm, no there is either no uname or uname has returned
        #'unknowns'... we'll have to poke around the system then.
        if no_os_uname:
            system = sys.platform
            release = ''
            version = ''
            node = _node()
            machine = ''

同样根据文档

os.uname()

返回一个5元组,其中包含标识当前操作系统的信息。元组包含5个字符串:(系统名称,节点名称,发行版,版本,计算机)。某些系统将节点名截断为8个字符或开头部分;获得主机名的更好方法是socket.gethostname()甚至socket.gethostbyaddr(socket.gethostname())。

Availability: recent flavors of Unix.

There is a thin line difference between platform.system() and sys.platform and interestingly for most cases platform.system() degenerates to sys.platform

Here is what the Source Python2.7\Lib\Platform.py\system says

def system():

    """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.

        An empty string is returned if the value cannot be determined.

    """
    return uname()[0]

def uname():
    # Get some infos from the builtin os.uname API...
    try:
        system,node,release,version,machine = os.uname()
    except AttributeError:
        no_os_uname = 1

    if no_os_uname or not filter(None, (system, node, release, version, machine)):
        # Hmm, no there is either no uname or uname has returned
        #'unknowns'... we'll have to poke around the system then.
        if no_os_uname:
            system = sys.platform
            release = ''
            version = ''
            node = _node()
            machine = ''

Also per the documentation

os.uname()

Return a 5-tuple containing information identifying the current operating system. The tuple contains 5 strings: (sysname, nodename, release, version, machine). Some systems truncate the nodename to 8 characters or to the leading component; a better way to get the hostname is socket.gethostname() or even socket.gethostbyaddr(socket.gethostname()).

Availability: recent flavors of Unix.

回答 2

sys.platform文档

通常,测试某些功能是否可用的“最好的”面向未来的方法只是尝试使用它,并在失败时使用备用。

sys.platform和platform.system()之间的区别如何?

platform.system()返回的标准值,它可能从多个来源获得:os.uname()sys.platformver命令(在Windows上)。

From sys.platform docs:

  • os.name has a coarser granularity
  • os.uname() gives system-dependent version information
  • The platform module provides detailed checks for the system’s identity

Often the “best” future-proof way to test whether some functionality is available is just to try to use it and use a fallback if it fails.

what about the difference between sys.platform and platform.system()?

platform.system() returns a normalized value that it might get from several sources: os.uname(), sys.platform, ver command (on Windows).


回答 3

这取决于您是希望在未测试的系统上引发异常还是尝试任何操作,以及您的代码是否如此高级或如此之低,以至于它在类似的未经测试的系统(例如未经测试的Mac-‘posix’或嵌入式ARM系统)。更多的pythonic方法不是枚举所有已知系统,而是测试可能的相关属性。(例如,重要的是系统的持久性,但不重要的多处理属性。)

  • os.name是正确使用os模块的足够分辨率。可能的值为Python 2.7中的’posix’,’nt’,’os2’,’ce’,’java’或’riscos’,而自Python 3.4起仅使用’posix’,’nt’和’java’。

  • sys.platform是更好的解决方案。建议使用if sys.platform.startswith('linux')成语,因为“ linux2”表示Linux内核版本为2.xx或3。目前从未使用过较早的内核。在Python 3.3中,所有Linux系统都是简单的“ Linux”。

我不知道“ Mac”和“ Java”系统的详细信息,因此我不能使用非常好的方法platform.system()的结果进行分支,但是我将利用platform模块的优势进行消息和错误记录。

It depends on whether you prefer raising exception or trying anything on an untested system and whether your code is so high level or so low level that it can or can’t work on a similar untested system (e.g. untested Mac – ‘posix’ or on embedded ARM systems). More pythonic is to not enumerate all known systems but to test possible relevant properties. (e.g. it is considered important the endianess of the system but unimportant multiprocessing properties.)

  • os.name is a sufficient resolution for the correct usage of os module. Possible values are ‘posix’, ‘nt’, ‘os2’, ‘ce’, ‘java’ or ‘riscos’ in Python 2.7, while only the ‘posix’, ‘nt’ and ‘java’ are used since Python 3.4.

  • sys.platform is a finer resolution. It is recommended to use if sys.platform.startswith('linux') idiom because “linux2” means a Linux kernel version 2.xx or 3. Older kernels are currently never used. In Python 3.3 are all Linux systems simple ‘linux’.

I do not know the specifics of “Mac” and “Java” systems and so I can not use the results of very good method platform.system() for branching, but I would use advantages of the platform module for messages and error logging.


回答 4

我相信平台模块可能是新代码的首选。其他人在此之前存在。这是一个演变,其余的则是为了向后兼容。

I believe the platform module is probably preferred for new code. The others existed before it. It is an evolution, and the others remain for backwards compatibility.


确定目录是否可写

问题:确定目录是否可写

在Python中确定执行脚本的用户是否可写目录的最佳方法是什么?因为这可能涉及使用os模块,所以我应该提到我是在* nix环境下运行它的。

What would be the best way in Python to determine whether a directory is writeable for the user executing the script? Since this will likely involve using the os module I should mention I’m running it under a *nix environment.


回答 0

尽管Christophe建议的是更Python化的解决方案,但os模块确实具有os.access函数来检查访问:

os.access('/path/to/folder', os.W_OK) #W_OK用于写入,R_OK用于读取,等等。

Although what Christophe suggested is a more Pythonic solution, the os module does have the os.access function to check access:

os.access('/path/to/folder', os.W_OK) # W_OK is for writing, R_OK for reading, etc.


回答 1

提出这个建议似乎很奇怪,但是一个常见的Python习惯用法是

寻求宽恕比获得许可要容易

遵循这一习语,人们可能会说:

尝试写入有问题的目录,如果没有权限,则捕获错误。

It may seem strange to suggest this, but a common Python idiom is

It’s easier to ask for forgiveness than for permission

Following that idiom, one might say:

Try writing to the directory in question, and catch the error if you don’t have the permission to do so.


回答 2

我使用tempfile模块的解决方案:

import tempfile
import errno

def isWritable(path):
    try:
        testfile = tempfile.TemporaryFile(dir = path)
        testfile.close()
    except OSError as e:
        if e.errno == errno.EACCES:  # 13
            return False
        e.filename = path
        raise
    return True

更新:在Windows上再次测试代码后,我发现在那里使用tempfile确实存在问题,请参见issue22107:tempfile模块错误地解释了Windows上的拒绝访问错误。对于不可写的目录,代码会挂起几秒钟,最后抛出IOError: [Errno 17] No usable temporary file name found。也许这是user2171842正在观察的内容?不幸的是,该问题暂时无法解决,因此要解决此问题,还必须捕获该错误:

    except (OSError, IOError) as e:
        if e.errno == errno.EACCES or e.errno == errno.EEXIST:  # 13, 17

那时在这些情况下当然仍然存在延迟。

My solution using the tempfile module:

import tempfile
import errno

def isWritable(path):
    try:
        testfile = tempfile.TemporaryFile(dir = path)
        testfile.close()
    except OSError as e:
        if e.errno == errno.EACCES:  # 13
            return False
        e.filename = path
        raise
    return True

Update: After testing the code again on Windows I see that there is indeed an issue when using tempfile there, see issue22107: tempfile module misinterprets access denied error on Windows. In the case of a non-writable directory, the code hangs for several seconds and finally throws an IOError: [Errno 17] No usable temporary file name found. Maybe this is what user2171842 was observing? Unfortunately the issue is not resolved for now so to handle this, the error needs to be catched as well:

    except (OSError, IOError) as e:
        if e.errno == errno.EACCES or e.errno == errno.EEXIST:  # 13, 17

The delay is of course still present in these cases then.


回答 3

偶然发现该线程在寻找某人的示例。恭喜,您在Google上获得了第一个结果!

人们谈论在此线程中使用Python的方式,但是没有简单的代码示例吗?在这里,对于任何偶然发现的人:

import sys

filepath = 'C:\\path\\to\\your\\file.txt'

try:
    filehandle = open( filepath, 'w' )
except IOError:
    sys.exit( 'Unable to write to file ' + filepath )

filehandle.write("I am writing this text to the file\n")

这会尝试打开文件句柄进行写入,如果指定的文件无法写入,则会退出并返回错误:这更容易阅读,并且比对文件路径或目录进行预检查要好得多,因为它避免了比赛条件;在运行预检查的时间到实际尝试写入文件之间文件不可写的情况。

Stumbled across this thread searching for examples for someone. First result on Google, congrats!

People talk about the Pythonic way of doing it in this thread, but no simple code examples? Here you go, for anyone else who stumbles in:

import sys

filepath = 'C:\\path\\to\\your\\file.txt'

try:
    filehandle = open( filepath, 'w' )
except IOError:
    sys.exit( 'Unable to write to file ' + filepath )

filehandle.write("I am writing this text to the file\n")

This attempts to open a filehandle for writing, and exits with an error if the file specified cannot be written to: This is far easier to read, and is a much better way of doing it rather than doing prechecks on the file path or the directory, as it avoids race conditions; cases where the file becomes unwriteable between the time you run the precheck, and when you actually attempt to write to the file.


回答 4

如果您只关心文件烫发,os.access(path, os.W_OK)应按要求进行操作。相反,如果您想知道是否可以写入该目录,则可以编写open()一个用于写入的测试文件(该文件不应事先存在),捕获并检查其中的任何IOError文件,然后清理该测试文件。

更一般而言,为避免TOCTOU攻击(仅当脚本以提升的特权-suid或cgi或更高的特权运行时才出现问题),您不应该真正信任这些提前测试,而应该放弃privs,执行open()并期望的IOError

If you only care about the file perms, os.access(path, os.W_OK) should do what you ask for. If you instead want to know whether you can write to the directory, open() a test file for writing (it shouldn’t exist beforehand), catch and examine any IOError, and clean up the test file afterwards.

More generally, to avoid TOCTOU attacks (only a problem if your script runs with elevated privileges — suid or cgi or so), you shouldn’t really trust these ahead-of-time tests, but drop privs, do the open(), and expect the IOError.


回答 5

检查模式位:

def isWritable(name):
  uid = os.geteuid()
  gid = os.getegid()
  s = os.stat(dirname)
  mode = s[stat.ST_MODE]
  return (
     ((s[stat.ST_UID] == uid) and (mode & stat.S_IWUSR)) or
     ((s[stat.ST_GID] == gid) and (mode & stat.S_IWGRP)) or
     (mode & stat.S_IWOTH)
     )

Check the mode bits:

def isWritable(name):
  uid = os.geteuid()
  gid = os.getegid()
  s = os.stat(dirname)
  mode = s[stat.ST_MODE]
  return (
     ((s[stat.ST_UID] == uid) and (mode & stat.S_IWUSR)) or
     ((s[stat.ST_GID] == gid) and (mode & stat.S_IWGRP)) or
     (mode & stat.S_IWOTH)
     )

回答 6

这是我根据ChristopheD的答案创建的:

import os

def isWritable(directory):
    try:
        tmp_prefix = "write_tester";
        count = 0
        filename = os.path.join(directory, tmp_prefix)
        while(os.path.exists(filename)):
            filename = "{}.{}".format(os.path.join(directory, tmp_prefix),count)
            count = count + 1
        f = open(filename,"w")
        f.close()
        os.remove(filename)
        return True
    except Exception as e:
        #print "{}".format(e)
        return False

directory = "c:\\"
if (isWritable(directory)):
    print "directory is writable"
else:
    print "directory is not writable"

Here is something I created based on ChristopheD’s answer:

import os

def isWritable(directory):
    try:
        tmp_prefix = "write_tester";
        count = 0
        filename = os.path.join(directory, tmp_prefix)
        while(os.path.exists(filename)):
            filename = "{}.{}".format(os.path.join(directory, tmp_prefix),count)
            count = count + 1
        f = open(filename,"w")
        f.close()
        os.remove(filename)
        return True
    except Exception as e:
        #print "{}".format(e)
        return False

directory = "c:\\"
if (isWritable(directory)):
    print "directory is writable"
else:
    print "directory is not writable"

回答 7

 if os.access(path_to_folder, os.W_OK) is not True:
            print("Folder not writable")
 else :
            print("Folder writable")

有关访问的更多信息可以在这里找到

 if os.access(path_to_folder, os.W_OK) is not True:
            print("Folder not writable")
 else :
            print("Folder writable")

more info about access can be find it here


回答 8

通过argparse添加参数时,我遇到了同样的需求。内置type=FileType('w')目录对我不起作用,因为我在寻找目录。我最终写出了自己的方法来解决我的问题。这是argparse代码段的结果。

#! /usr/bin/env python
import os
import argparse

def writable_dir(dir):
    if os.access(dir, os.W_OK) and os.path.isdir(dir):
        return os.path.abspath(dir)
    else:
        raise argparse.ArgumentTypeError(dir + " is not writable or does not exist.")

parser = argparse.ArgumentParser()
parser.add_argument("-d","--dir", type=writable_dir(), default='/tmp/',
    help="Directory to use. Default: /tmp")
opts = parser.parse_args()

结果如下:

$ python dir-test.py -h
usage: dir-test.py [-h] [-d DIR]

optional arguments:
  -h, --help         show this help message and exit
  -d DIR, --dir DIR  Directory to use. Default: /tmp

$ python dir-test.py -d /not/real
usage: dir-test.py [-h] [-d DIR]
dir-test.py: error: argument -d/--dir: /not/real is not writable or does not exist.

$ python dir-test.py -d ~

回过头来,在最后添加了print opts.dir,一切似乎都可以正常运行了。

I ran into this same need while adding an argument via argparse. The built in type=FileType('w') wouldn’t work for me as I was looking for a directory. I ended up writing my own method to solve my problem. Here is the result with argparse snippet.

#! /usr/bin/env python
import os
import argparse

def writable_dir(dir):
    if os.access(dir, os.W_OK) and os.path.isdir(dir):
        return os.path.abspath(dir)
    else:
        raise argparse.ArgumentTypeError(dir + " is not writable or does not exist.")

parser = argparse.ArgumentParser()
parser.add_argument("-d","--dir", type=writable_dir(), default='/tmp/',
    help="Directory to use. Default: /tmp")
opts = parser.parse_args()

That results in the following:

$ python dir-test.py -h
usage: dir-test.py [-h] [-d DIR]

optional arguments:
  -h, --help         show this help message and exit
  -d DIR, --dir DIR  Directory to use. Default: /tmp

$ python dir-test.py -d /not/real
usage: dir-test.py [-h] [-d DIR]
dir-test.py: error: argument -d/--dir: /not/real is not writable or does not exist.

$ python dir-test.py -d ~

I went back and added print opts.dir to the end, and everything appears to be functioning as desired.


回答 9

如果您需要检查其他用户的权限(是的,我知道这与问题相矛盾,但可能对某人有用),则可以通过pwd模块和目录的模式位来进行检查。

免责声明 -在Windows上不起作用,因为它不使用POSIX权限模型(并且该pwd模块在那里不可用),例如-仅针对* nix系统的解决方案。

请注意,目录必须设置所有3位-读,写和eXecute。
好的,R不是绝对必须的,但是没有,您不能在目录中列出条目(因此您必须知道它们的名称)。另一方面,绝对需要执行-没有用户无法读取文件的inode;因此即使没有W也无法创建或修改W。在此链接上有更详细的说明。

最后,这些模式在stat模块中可用,其描述在inode(7)man中

示例代码如何检查:

import pwd
import stat
import os

def check_user_dir(user, directory):
    dir_stat = os.stat(directory)

    user_id, group_id = pwd.getpwnam(user).pw_uid, pwd.getpwnam(user).pw_gid
    directory_mode = dir_stat[stat.ST_MODE]

    # use directory_mode as mask 
    if user_id == dir_stat[stat.ST_UID] and stat.S_IRWXU & directory_mode == stat.S_IRWXU:     # owner and has RWX
        return True
    elif group_id == dir_stat[stat.ST_GID] and stat.S_IRWXG & directory_mode == stat.S_IRWXG:  # in group & it has RWX
        return True
    elif stat.S_IRWXO & directory_mode == stat.S_IRWXO:                                        # everyone has RWX
        return True

    # no permissions
    return False

If you need to check the permission of another user (yes, I realize this contradicts the question, but may come in handy for someone), you can do it through the pwd module, and the directory’s mode bits.

Disclaimer – does not work on Windows, as it doesn’t use the POSIX permissions model (and the pwd module is not available there), e.g. – solution only for *nix systems.

Note that a directory has to have all the 3 bits set – Read, Write and eXecute.
Ok, R is not an absolute must, but w/o it you cannot list the entries in the directory (so you have to know their names). Execute on the other hand is absolutely needed – w/o it the user cannot read the file’s inodes; so even having W, without X files cannot be created or modified. More detailed explanation at this link.

Finally, the modes are available in the stat module, their descriptions are in inode(7) man.

Sample code how to check:

import pwd
import stat
import os

def check_user_dir(user, directory):
    dir_stat = os.stat(directory)

    user_id, group_id = pwd.getpwnam(user).pw_uid, pwd.getpwnam(user).pw_gid
    directory_mode = dir_stat[stat.ST_MODE]

    # use directory_mode as mask 
    if user_id == dir_stat[stat.ST_UID] and stat.S_IRWXU & directory_mode == stat.S_IRWXU:     # owner and has RWX
        return True
    elif group_id == dir_stat[stat.ST_GID] and stat.S_IRWXG & directory_mode == stat.S_IRWXG:  # in group & it has RWX
        return True
    elif stat.S_IRWXO & directory_mode == stat.S_IRWXO:                                        # everyone has RWX
        return True

    # no permissions
    return False

为什么要使用Python的os模块方法而不是直接执行shell命令?

问题:为什么要使用Python的os模块方法而不是直接执行shell命令?

我试图了解使用Python的库函数执行特定于操作系统的任务(例如创建文件/目录,更改文件属性等)的动机是什么,而不是仅通过os.system()or 来执行这些命令subprocess.call()

例如,为什么我要使用os.chmod而不是做os.system("chmod...")

我知道,尽可能多地使用Python的可用库方法,而不是直接执行Shell命令,更像是“ Pythonic”。但是,从功能角度来看,这样做还有其他动机吗?

我只在这里谈论执行简单的单行shell命令。当我们需要对任务的执行进行更多控制时,我知道subprocess例如使用模块更有意义。

I am trying to understand what is the motivation behind using Python’s library functions for executing OS-specific tasks such as creating files/directories, changing file attributes, etc. instead of just executing those commands via os.system() or subprocess.call()?

For example, why would I want to use os.chmod instead of doing os.system("chmod...")?

I understand that it is more “pythonic” to use Python’s available library methods as much as possible instead of just executing shell commands directly. But, is there any other motivation behind doing this from a functionality point of view?

I am only talking about executing simple one-line shell commands here. When we need more control over the execution of the task, I understand that using subprocess module makes more sense, for example.


回答 0

  1. 速度更快os.systemsubprocess.call创建了新的流程,而这对于这种简单的操作是不必要的。事实上,os.systemsubprocess.callshell参数通常至少创建两个新的流程:第一个是罩,而第二个是命令,你正在运行(如果它不是内置像贝壳test)。

  2. 有些命令在单独的过程没有用。例如,如果运行os.spawn("cd dir/"),它将更改子进程的当前工作目录,但不会更改Python进程的当前工作目录。您需要使用os.chdir它。

  3. 您不必担心shell 解释的特殊字符os.chmod(path, mode)不管文件名是什么都可以使用,而os.spawn("chmod 777 " + path)如果文件名是则将失败; rm -rf ~。(请注意,如果subprocess.call不带shell参数使用,可以解决此问题。)

  4. 您不必担心以破折号开头的文件名os.chmod("--quiet", mode)将更改名为的文件的权限--quiet,但os.spawn("chmod 777 --quiet")会失败,因为--quiet会解释为参数。即使这样,也是如此subprocess.call(["chmod", "777", "--quiet"])

  5. 您可以减少跨平台和跨外壳的问题,因为Python的标准库应该可以为您解决这些问题。您的系统有chmod命令吗?安装好了吗?它支持您期望它支持的参数吗?该os模块将尝试尽可能地跨平台,并在不可能的情况下进行记录。

  6. 如果您正在运行的命令具有您所关心的输出,则需要对其进行解析,这比听起来要棘手,因为您可能会忘记了极端情况(其中包含空格,制表符和换行符的文件名),即使您不在乎可移植性。

  1. It’s faster, os.system and subprocess.call create new processes which is unnecessary for something this simple. In fact, os.system and subprocess.call with the shell argument usually create at least two new processes: the first one being the shell, and the second one being the command that you’re running (if it’s not a shell built-in like test).

  2. Some commands are useless in a separate process. For example, if you run os.spawn("cd dir/"), it will change the current working directory of the child process, but not of the Python process. You need to use os.chdir for that.

  3. You don’t have to worry about special characters interpreted by the shell. os.chmod(path, mode) will work no matter what the filename is, whereas os.spawn("chmod 777 " + path) will fail horribly if the filename is something like ; rm -rf ~. (Note that you can work around this if you use subprocess.call without the shell argument.)

  4. You don’t have to worry about filenames that begin with a dash. os.chmod("--quiet", mode) will change the permissions of the file named --quiet, but os.spawn("chmod 777 --quiet") will fail, as --quiet is interpreted as an argument. This is true even for subprocess.call(["chmod", "777", "--quiet"]).

  5. You have fewer cross-platform and cross-shell concerns, as Python’s standard library is supposed to deal with that for you. Does your system have chmod command? Is it installed? Does it support the parameters that you expect it to support? The os module will try to be as cross-platform as possible and documents when that it’s not possible.

  6. If the command you’re running has output that you care about, you need to parse it, which is trickier than it sounds, as you may forget about corner-cases (filenames with spaces, tabs and newlines in them), even when you don’t care about portability.


回答 1

更安全。这里给你一个想法是一个示例脚本

import os
file = raw_input("Please enter a file: ")
os.system("chmod 777 " + file)

如果来自用户的输入是test; rm -rf ~,则将删除主目录。

这就是为什么使用内置函数更安全的原因。

因此,为什么还要使用子流程而不是系统。

It is safer. To give you an idea here is an example script

import os
file = raw_input("Please enter a file: ")
os.system("chmod 777 " + file)

If the input from the user was test; rm -rf ~ this would then delete the home directory.

This is why it is safer to use the built in function.

Hence why you should use subprocess instead of system too.


回答 2

在执行命令时,有四种很强的情况os比起使用os.systemsubprocess模块,更喜欢在模块中使用Python更具体的方法:

  • 冗余 -产生另一个进程是多余的,浪费时间和资源。
  • 可移植性os模块中的许多方法可在多个平台上使用,而许多shell命令是特定于OS的。
  • 了解结果 -生成执行任意命令的进程会迫使您从输出中解析结果,并了解命令是否以及为什么做错了什么。
  • 安全 -进程可以执行它给出的任何命令。这是一个较弱的设计,可以通过使用os模块中的特定方法来避免。

冗余(请参阅冗余代码):

实际上,您在执行最终系统调用的过程chmod中正在执行一个冗余的“中间人”(在您的示例中)。这个中间人是一个新的进程或子外壳。

来自os.system

在子shell中执行命令(字符串)…

并且subprocess仅仅是产生新流程的模块。

您可以执行所需的操作而无需产生这些过程。

可移植性(请参阅源代码可移植性):

os模块的目的是提供通用的操作系统服务,其描述始于:

该模块提供了使用依赖于操作系统的功能的便携式方法。

您可以os.listdir在Windows和Unix上使用。尝试将os.system/ subprocess用于此功能将迫使您维护两个调用(ls/ dir),并检查您所使用的操作系统。这不是便携式的,以后引起更大的挫败感(请参阅处理输出)。

了解命令的结果:

假设您要列出目录中的文件。

如果使用os.system("ls")/ subprocess.call(['ls']),则只能返回该进程的输出,这基本上是一个带有文件名的大字符串。

如何从两个文件中分辨出文件名中带有空格的文件?

如果您无权列出文件怎么办?

您应该如何将数据映射到python对象?

这些只是我的头上问题,尽管有解决这些问题的方法-为什么要再次解决为您解决的问题?

这是通过重复已经存在且可供您免费使用的实现来遵循“ 不要重复自己”原理(通常称为“ DRY”)的示例。

安全:

os.system并且subprocess功能强大。当您需要这种功能时,这很好,但是当您不需要这种功能时,这是危险的。使用时os.listdir,您知道它只能执行其他操作,然后列出文件或引发错误。当您使用os.systemsubprocess实现相同的行为时,您可能最终会做一些原本不想做的事情。

注射安全性(请参见外壳注射示例

如果将来自用户的输入用作新命令,则基本上已经给了他一个外壳。这就像SQL注入为用户在DB中提供外壳程序一样。

一个示例将是以下形式的命令:

# ... read some user input
os.system(user_input + " some continutation")

这可以很容易利用来运行任何使用输入任意代码:NASTY COMMAND;#创建最终的:

os.system("NASTY COMMAND; # some continuation")

有许多这样的命令会使您的系统处于危险之中。

There are four strong cases for preferring Python’s more-specific methods in the os module over using os.system or the subprocess module when executing a command:

  • Redundancy – spawning another process is redundant and wastes time and resources.
  • Portability – Many of the methods in the os module are available in multiple platforms while many shell commands are os-specific.
  • Understanding the results – Spawning a process to execute arbitrary commands forces you to parse the results from the output and understand if and why a command has done something wrong.
  • Safety – A process can potentially execute any command it’s given. This is a weak design and it can be avoided by using specific methods in the os module.

Redundancy (see redundant code):

You’re actually executing a redundant “middle-man” on your way to the eventual system calls (chmod in your example). This middle man is a new process or sub-shell.

From os.system:

Execute the command (a string) in a subshell …

And subprocess is just a module to spawn new processes.

You can do what you need without spawning these processes.

Portability (see source code portability):

The os module’s aim is to provide generic operating-system services and it’s description starts with:

This module provides a portable way of using operating system dependent functionality.

You can use os.listdir on both windows and unix. Trying to use os.system / subprocess for this functionality will force you to maintain two calls (for ls / dir) and check what operating system you’re on. This is not as portable and will cause even more frustration later on (see Handling Output).

Understanding the command’s results:

Suppose you want to list the files in a directory.

If you’re using os.system("ls") / subprocess.call(['ls']), you can only get the process’s output back, which is basically a big string with the file names.

How can you tell a file with a space in it’s name from two files?

What if you have no permission to list the files?

How should you map the data to python objects?

These are only off the top of my head, and while there are solutions to these problems – why solve again a problem that was solved for you?

This is an example of following the Don’t Repeat Yourself principle (Often reffered to as “DRY”) by not repeating an implementation that already exists and is freely available for you.

Safety:

os.system and subprocess are powerful. It’s good when you need this power, but it’s dangerous when you don’t. When you use os.listdir, you know it can not do anything else other then list files or raise an error. When you use os.system or subprocess to achieve the same behaviour you can potentially end up doing something you did not mean to do.

Injection Safety (see shell injection examples):

If you use input from the user as a new command you’ve basically given him a shell. This is much like SQL injection providing a shell in the DB for the user.

An example would be a command of the form:

# ... read some user input
os.system(user_input + " some continutation")

This can be easily exploited to run any arbitrary code using the input: NASTY COMMAND;# to create the eventual:

os.system("NASTY COMMAND; # some continuation")

There are many such commands that can put your system at risk.


回答 3

出于简单的原因-当您调用shell函数时,它将创建一个子shell,该子shell在命令存在后会被破坏,因此,如果您在shell中更改目录,则不会影响您在Python中的环境。

此外,创建子外壳非常耗时,因此直接使用OS命令将影响您的性能。

编辑

我正在运行一些计时测试:

In [379]: %timeit os.chmod('Documents/recipes.txt', 0755)
10000 loops, best of 3: 215 us per loop

In [380]: %timeit os.system('chmod 0755 Documents/recipes.txt')
100 loops, best of 3: 2.47 ms per loop

In [382]: %timeit call(['chmod', '0755', 'Documents/recipes.txt'])
100 loops, best of 3: 2.93 ms per loop

内部功能运行速度提高10倍以上

编辑2

在某些情况下,调用外部可执行文件可能比Python软件包产生更好的结果-我刚刚记得我的一位同事发送的一封邮件,其中说通过子进程调用的gzip的性能比他使用的Python软件包的性能高得多。但是当我们谈论模拟标准OS命令的标准OS软件包时肯定不会

For a simple reason – when you call a shell function, it creates a sub-shell which is destroyed after your command exists, so if you change directory in a shell – it does not affect your environment in Python.

Besides, creating sub-shell is time consuming, so using OS commands directly will impact your performance

EDIT

I had some timing tests running:

In [379]: %timeit os.chmod('Documents/recipes.txt', 0755)
10000 loops, best of 3: 215 us per loop

In [380]: %timeit os.system('chmod 0755 Documents/recipes.txt')
100 loops, best of 3: 2.47 ms per loop

In [382]: %timeit call(['chmod', '0755', 'Documents/recipes.txt'])
100 loops, best of 3: 2.93 ms per loop

Internal function runs more than 10 time faster

EDIT2

There may be cases when invoking external executable may yield better results than Python packages – I just remembered a mail sent by a colleague of mine that performance of gzip called through subprocess was much higher than the performance of a Python package he used. But certainly not when we are talking about standard OS packages emulating standard OS commands


回答 4

Shell调用是特定于OS的,而在大多数情况下不是Python os模块的功能。并且避免产生子流程。

Shell call are OS specific whereas Python os module functions are not, in most of the case. And it avoid spawning a subprocess.


回答 5

效率更高。“ shell”只是另一个OS二进制文件,其中包含许多系统调用。为什么只为单个系统调用而产生创建整个Shell进程的开销?

当您使用os.system的不是内置shell 时,情况甚至更糟。您启动一个Shell进程,然后启动一个可执行文件,然后该可执行文件(两个进程分开)进行系统调用。至少subprocess可以消除对shell中介过程的需求。

这不是特定于Python的。systemd出于相同的原因,它大大缩短了Linux启动时间:它使必要的系统调用本身而不是产生一千个shell。

It’s far more efficient. The “shell” is just another OS binary which contains a lot of system calls. Why incur the overhead of creating the whole shell process just for that single system call?

The situation is even worse when you use os.system for something that’s not a shell built-in. You start a shell process which in turn starts an executable which then (two processes away) makes the system call. At least subprocess would have removed the need for a shell intermediary process.

It’s not specific to Python, this. systemd is such an improvement to Linux startup times for the same reason: it makes the necessary system calls itself instead of spawning a thousand shells.


如何在Python中获取PATH环境变量分隔符?

问题:如何在Python中获取PATH环境变量分隔符?

当需要将多个目录串联在一起时(例如在可执行文件搜索路径中),存在一个与OS相关的分隔符。对于Windows ';',对于Linux':'。Python中有没有一种方法可以分割哪个字符?

在对此问题的讨论中,如何使用python找出我的python路径?,建议这样os.sep做。这个答案是错误的,因为它是目录或文件名组成部分的分隔符,等于'\\''/'

When multiple directories need to be concatenated, as in an executable search path, there is an os-dependent separator character. For Windows it’s ';', for Linux it’s ':'. Is there a way in Python to get which character to split on?

In the discussions to this question How do I find out my python path using python? , it is suggested that os.sep will do it. That answer is wrong, since it is the separator for components of a directory or filename and equates to '\\' or '/'.


回答 0


回答 1

它是os.pathsep

It is os.pathsep


回答 2

使它更加明确(对于像我这样的python新手)

import os
print(os.pathsep)

Making it a little more explicit (For python newbies like me)

import os
print(os.pathsep)

回答 3

好,所以有:

  • os.pathsep这是;并且是PATH环境变量中的分隔符;
  • os.path.sep/在Unix / Linux和\Windows中,这是路径成分之间的隔板。

相似性是造成混乱的根源。

OK, so there are:

  • os.pathsep that is ; and which is a separator in the PATH environment variable;
  • os.path.sep that is / in Unix/Linux and \ in Windows, which is a separator between path components.

The similarity is a source of confusion.


回答 4

这是您的工作目录/特定文件夹的示例路径-

 import os
 my = os.path.sep+ "testImages" + os.path.sep + "imageHidden.png"
 print(my)

Linux-的输出

/home/*******/Desktop/folder/PlayWithPy/src/testImages/imageHidden.png

Windows输出

C:\\Users\\Administrator\\Desktop\\folder\\tests\\testImages\\imageHidden.png

This is a sample path for your working directory/specific folder –

 import os
 my = os.path.sep+ "testImages" + os.path.sep + "imageHidden.png"
 print(my)

Output for Linux-

/home/*******/Desktop/folder/PlayWithPy/src/testImages/imageHidden.png

Output for Windows-

C:\\Users\\Administrator\\Desktop\\folder\\tests\\testImages\\imageHidden.png


如何检查Python中的操作系统?

问题:如何检查Python中的操作系统?

我想检查操作系统(在运行脚本的计算机上)。

我知道我可以os.system('uname -o')在Linux 中使用,但是它在控制台中给了我一条消息,并且我想写一个变量。

如果脚本可以告诉您它是Mac,Windows还是Linux,那就可以了。我该如何检查?

I want to check the operating system (on the computer where the script runs).

I know I can use os.system('uname -o') in Linux, but it gives me a message in the console, and I want to write to a variable.

It will be okay if the script can tell if it is Mac, Windows or Linux. How can I check it?


回答 0

您可以使用sys.platform

from sys import platform
if platform == "linux" or platform == "linux2":
    # linux
elif platform == "darwin":
    # OS X
elif platform == "win32":
    # Windows...

sys.platform具有比更好的粒度sys.name

有关有效值,请参阅文档

另请参见“我正在运行什么操作系统?”的答案

You can use sys.platform:

from sys import platform
if platform == "linux" or platform == "linux2":
    # linux
elif platform == "darwin":
    # OS X
elif platform == "win32":
    # Windows...

sys.platform has finer granularity than sys.name.

For the valid values, consult the documentation.

See also the answer to “What OS am I running on?”


回答 1

如果您想更精确地了解使用“ Linux”,“ Windows”或“ Darwin”(Mac)的平台,则应使用:

>>> import platform
>>> platform.system()
'Linux'  # or 'Windows'/'Darwin'

platform.system函数在uname内部使用。

If you want to know on which platform you are on out of “Linux”, “Windows”, or “Darwin” (Mac), without more precision, you should use:

>>> import platform
>>> platform.system()
'Linux'  # or 'Windows'/'Darwin'

The platform.system function uses uname internally.


回答 2

通过检查,您可以大致了解所使用的操作系统sys.platform

获得这些信息后,您可以使用它来确定调用类似的东西os.uname()是否适合收集更具体的信息。您也可以在类似Unix的操作系统上使用Python系统信息,或者在Windows 上使用pywin32

如果您想进行更深入的检查而又不想关心操作系统,那么也可以使用psutil

You can get a pretty coarse idea of the OS you’re using by checking sys.platform.

Once you have that information you can use it to determine if calling something like os.uname() is appropriate to gather more specific information. You could also use something like Python System Information on unix-like OSes, or pywin32 for Windows.

There’s also psutil if you want to do more in-depth inspection without wanting to care about the OS.


回答 3

platform模块中提供了更多详细信息。

More detailed information are available in the platform module.


回答 4

您可以使用sys.platform


如何安全地创建嵌套目录?

问题:如何安全地创建嵌套目录?

检查文件目录是否存在的最优雅方法是什么,如果不存在,则使用Python创建目录?这是我尝试过的:

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)

是否有“打开”标志,使它自动发生?

What is the most elegant way to check if the directory a file is going to be written to exists, and if not, create the directory using Python? Here is what I tried:

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)

Somehow, I missed os.path.exists (thanks kanja, Blair, and Douglas). This is what I have now:

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

Is there a flag for “open”, that makes this happen automatically?


回答 0

在Python≥3.5上,使用pathlib.Path.mkdir

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

对于旧版本的Python,我看到两个质量很好的答案,每个都有一个小缺陷,因此我将对此进行说明:

试试看os.path.exists,然后考虑os.makedirs创建。

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

如注释和其他地方所述,存在竞争条件–如果在os.path.existsos.makedirs调用之间创建目录,os.makedirs则将失败并显示OSError。不幸的是,毯式捕获OSError和继续操作并非万无一失,因为它将忽略由于其他因素(例如权限不足,磁盘已满等)而导致的目录创建失败。

一种选择是捕获OSError并检查嵌入式错误代码(请参阅是否存在从Python的OSError获取信息的跨平台方法):

import os, errno

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

或者,可以有第二个os.path.exists,但是假设另一个在第一次检查后创建了目录,然后在第二个检查之前将其删除了–我们仍然可能会上当。

取决于应用程序,并发操作的危险可能比其他因素(例如文件许可权)造成的危险更大或更小。在选择实现之前,开发人员必须了解有关正在开发的特定应用程序及其预期环境的更多信息。

现代版本的Python通过暴露FileExistsError(在3.3+ 版本中)都极大地改善了此代码。

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

…并允许关键字参数os.makedirs调用exist_ok(在3.2+版本中)。

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

On Python ≥ 3.5, use pathlib.Path.mkdir:

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

For older versions of Python, I see two answers with good qualities, each with a small flaw, so I will give my take on it:

Try os.path.exists, and consider os.makedirs for the creation.

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

As noted in comments and elsewhere, there’s a race condition – if the directory is created between the os.path.exists and the os.makedirs calls, the os.makedirs will fail with an OSError. Unfortunately, blanket-catching OSError and continuing is not foolproof, as it will ignore a failure to create the directory due to other factors, such as insufficient permissions, full disk, etc.

One option would be to trap the OSError and examine the embedded error code (see Is there a cross-platform way of getting information from Python’s OSError):

import os, errno

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

Alternatively, there could be a second os.path.exists, but suppose another created the directory after the first check, then removed it before the second one – we could still be fooled.

Depending on the application, the danger of concurrent operations may be more or less than the danger posed by other factors such as file permissions. The developer would have to know more about the particular application being developed and its expected environment before choosing an implementation.

Modern versions of Python improve this code quite a bit, both by exposing FileExistsError (in 3.3+)…

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

…and by allowing a keyword argument to os.makedirs called exist_ok (in 3.2+).

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

回答 1

Python 3.5以上版本:

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

pathlib.Path.mkdir上面使用的递归方式创建目录,并且如果目录已经存在,则不会引发异常。如果不需要或不希望创建父母,请跳过该parents参数。

Python 3.2+:

使用pathlib

如果可以,请安装pathlib名为的当前反向端口pathlib2。不要安装名为的较旧的未维护的反向端口pathlib。接下来,请参考上面的Python 3.5+部分,并对其进行相同的使用。

如果使用Python 3.4,即使它附带了pathlib,它也会丢失有用的exist_ok选项。反向端口旨在提供更新的高级实现,mkdir其中包括缺少的选项。

使用os

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

os.makedirs上面使用的递归方式创建目录,并且如果目录已经存在,则不会引发异常。exist_ok仅当使用Python 3.2+时,它才具有可选参数,默认值为False。在2.7之前的Python 2.x中不存在此参数。这样,就不需要像Python 2.7那样的手动异常处理。

Python 2.7+:

使用pathlib

如果可以,请安装pathlib名为的当前反向端口pathlib2。不要安装名为的较旧的未维护的反向端口pathlib。接下来,请参考上面的Python 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创建嵌套目录,如果目录已经存在,则不执行任何操作。这适用于Python 2和3。

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

根据Bug 10948,此替代方案的严重局限性在于,对于给定路径,每个python进程仅工作一次。换句话说,如果您使用它来创建目录,然后从Python内部或外部删除该目录,然后mkpath再次mkpath使用它来重新创建同一目录,则将仅默默地使用其先前已创建目录的无效缓存信息,而不会实际再次创建目录。相反,os.makedirs不依赖任何此类缓存。对于某些应用程序,此限制可能是可以的。


关于目录的模式,如果您关心它,请参考文档。

Python 3.5+:

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

pathlib.Path.mkdir as used above recursively creates the directory and does not raise an exception if the directory already exists. If you don’t need or want the parents to be created, skip the parents argument.

Python 3.2+:

Using pathlib:

If you can, install the current pathlib backport named pathlib2. Do not install the older unmaintained backport named pathlib. Next, refer to the Python 3.5+ section above and use it the same.

If using Python 3.4, even though it comes with pathlib, it is missing the useful exist_ok option. The backport is intended to offer a newer and superior implementation of mkdir which includes this missing option.

Using os:

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

os.makedirs as used above recursively creates the directory and does not raise an exception if the directory already exists. It has the optional exist_ok argument only if using Python 3.2+, with a default value of False. This argument does not exist in Python 2.x up to 2.7. As such, there is no need for manual exception handling as with Python 2.7.

Python 2.7+:

Using pathlib:

If you can, install the current pathlib backport named pathlib2. Do not install the older unmaintained backport named pathlib. Next, refer to the Python 3.5+ section above and use it the same.

Using os:

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

While a naive solution may first use os.path.isdir followed by os.makedirs, the solution above reverses the order of the two operations. In doing so, it prevents a common race condition having to do with a duplicated attempt at creating the directory, and also disambiguates files from directories.

Note that capturing the exception and using errno is of limited usefulness because OSError: [Errno 17] File exists, i.e. errno.EEXIST, is raised for both files and directories. It is more reliable simply to check if the directory exists.

Alternative:

mkpath creates the nested directory, and does nothing if the directory already exists. This works in both Python 2 and 3.

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

Per Bug 10948, a severe limitation of this alternative is that it works only once per python process for a given path. In other words, if you use it to create a directory, then delete the directory from inside or outside Python, then use mkpath again to recreate the same directory, mkpath will simply silently use its invalid cached info of having previously created the directory, and will not actually make the directory again. In contrast, os.makedirs doesn’t rely on any such cache. This limitation may be okay for some applications.


With regard to the directory’s mode, please refer to the documentation if you care about it.


回答 2

使用tryexcept和来自errno模块的正确错误代码摆脱了竞争条件,并且是跨平台的:

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)。

Using try except and the right error code from errno module gets rid of the race condition and is cross-platform:

import os
import errno

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

In other words, we try to create the directories, but if they already exist we ignore the error. On the other hand, any other error gets reported. For example, if you create dir ‘a’ beforehand and remove all permissions from it, you will get an OSError raised with errno.EACCES (Permission denied, error 13).


回答 3

我个人建议您使用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()

I would personally recommend that you use os.path.isdir() to test instead of 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

If you have:

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

And a foolish user input:

:: /tmp/dirname/filename.etc

… You’re going to end up with a directory named filename.etc when you pass that argument to os.makedirs() if you test with os.path.exists().


回答 4

检查os.makedirs:(确保存在完整路径。)
要处理目录可能存在的事实,请catch OSError。(如果exist_okFalse(缺省值),OSError则在目标目录已经存在时引发。)

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

Check os.makedirs: (It makes sure the complete path exists.)
To handle the fact the directory might exist, catch OSError. (If exist_ok is False (the default), an OSError is raised if the target directory already exists.)

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

回答 5

从Python 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)

这将以递归方式创建目录,并且如果目录已经存在,则不会引发异常。

(就像从python 3.2开始os.makedirsexist_ok标志一样os.makedirs(path, exist_ok=True)

Starting from Python 3.5, pathlib.Path.mkdir has an exist_ok flag:

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

This recursively creates the directory and does not raise an exception if the directory already exists.

(just as os.makedirs got an exist_ok flag starting from python 3.2 e.g os.makedirs(path, exist_ok=True))


回答 6

对这种情况的具体见解

您在特定路径下提供特定文件,然后从文件路径中提取目录。然后,在确保您拥有目录之后,尝试打开一个文件进行读取。要对此代码发表评论:

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追加)。使用上下文管理器打开文件也是Python的最佳实践。

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

但是,假设我们有几个Python进程试图将其所有数据放入同一目录。然后,我们可能会争执目录的创建。在这种情况下,最好将makedirs调用包装在try-except块中。

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)

Insights on the specifics of this situation

You give a particular file at a certain path and you pull the directory from the file path. Then after making sure you have the directory, you attempt to open a file for reading. To comment on this code:

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

We want to avoid overwriting the builtin function, dir. Also, filepath or perhaps fullfilepath is probably a better semantic name than filename so this would be better written:

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

Your end goal is to open this file, you initially state, for writing, but you’re essentially approaching this goal (based on your code) like this, which opens the file for reading:

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

Assuming opening for reading

Why would you make a directory for a file that you expect to be there and be able to read?

Just attempt to open the file.

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

If the directory or file isn’t there, you’ll get an IOError with an associated error number: errno.ENOENT will point to the correct error number regardless of your platform. You can catch it if you want, for example:

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

Assuming we’re opening for writing

This is probably what you’re wanting.

In this case, we probably aren’t facing any race conditions. So just do as you were, but note that for writing, you need to open with the w mode (or a to append). It’s also a Python best practice to use the context manager for opening files.

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

However, say we have several Python processes that attempt to put all their data into the same directory. Then we may have contention over creation of the directory. In that case it’s best to wrap the makedirs call in a try-except block.

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)

回答 7

试用os.path.exists功能

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

Try the os.path.exists function

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

回答 8

我将以下内容放下。但是,这并非完全安全。

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

现在,正如我所说,这并不是万无一失的,因为我们有可能无法创建目录,而在此期间可能会有另一个创建它的进程。

I have put the following down. It’s not totally foolproof though.

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

Now as I say, this is not really foolproof, because we have the possiblity of failing to create the directory, and another process creating it during that period.


回答 9

检查目录是否存在并根据需要创建目录?

对此的直接答案是,假设有一个简单的情况,您不希望其他用户或进程弄乱您的目录:

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.

新的Python 3.5:pathlib.Pathexist_ok

有一个新的Path对象(从3.4版开始),它具有许多要与路径一起使用的方法-其中一个是mkdir

(在上下文中,我正在使用脚本跟踪我的每周代表。这是脚本中代码的相关部分,这些内容使我避免对同一数据每天多次遇到Stack Overflow。)

首先相关进口:

from pathlib import Path
import tempfile

我们现在不必处理os.path.join-只需将路径部分与结合起来即可/

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

然后,我确定地确保目录存在- exist_ok参数在Python 3.5中显示:

directory.mkdir(exist_ok=True)

这是文档的相关部分:

如果exist_ok为true,FileExistsErrorPOSIX 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路径使用它们的API 。

也许应该更新Pandas以接受抽象基类的实例os.PathLike

Check if a directory exists and create it if necessary?

The direct answer to this is, assuming a simple situation where you don’t expect other users or processes to be messing with your directory:

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

or if making the directory is subject to race conditions (i.e. if after checking the path exists, something else may have already made it) do this:

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

But perhaps an even better approach is to sidestep the resource contention issue, by using temporary directories via tempfile:

import tempfile

d = tempfile.mkdtemp()

Here’s the essentials from the online doc:

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.

New in Python 3.5: pathlib.Path with exist_ok

There’s a new Path object (as of 3.4) with lots of methods one would want to use with paths – one of which is mkdir.

(For context, I’m tracking my weekly rep with a script. Here’s the relevant parts of code from the script that allow me to avoid hitting Stack Overflow more than once a day for the same data.)

First the relevant imports:

from pathlib import Path
import tempfile

We don’t have to deal with os.path.join now – just join path parts with a /:

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

Then I idempotently ensure the directory exists – the exist_ok argument shows up in Python 3.5:

directory.mkdir(exist_ok=True)

Here’s the relevant part of the documentation:

If exist_ok is true, FileExistsError exceptions will be ignored (same behavior as the POSIX mkdir -p command), but only if the last path component is not an existing non-directory file.

Here’s a little more of the script – in my case, I’m not subject to a race condition, I only have one process that expects the directory (or contained files) to be there, and I don’t have anything trying to remove the directory.

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 objects have to be coerced to str before other APIs that expect str paths can use them.

Perhaps Pandas should be updated to accept instances of the abstract base class, os.PathLike.


回答 10

在Python 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.

In Python 3.4 you can also use the brand new pathlib module:

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.

回答 11

相关的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

该文档正是由于此问题中讨论的种族条件而提出了这一建议。此外,正如此处其他人所提到的,查询一次操作系统而不是两次查询操作系统具有性能优势。最后,在某些情况下(当开发人员知道应用程序正在运行的环境时),可能会提出支持第二个代码的参数,只有在特殊情况下才提倡该程序已为该程序建立了私有环境。本身(以及同一程序的其他实例)。

即使在这种情况下,这也是一种不好的做法,并且可能导致长时间的无用调试。例如,我们为目录设置权限的事实不应该使我们拥有为我们目的而适当设置的印象权限。可以使用其他权限挂载父目录。通常,程序应始终正常运行,并且程序员不应期望一个特定的环境。

The relevant Python documentation suggests the use of the EAFP coding style (Easier to Ask for Forgiveness than Permission). This means that the code

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

is better than the alternative

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

The documentation suggests this exactly because of the race condition discussed in this question. In addition, as others mention here, there is a performance advantage in querying once instead of twice the OS. Finally, the argument placed forward, potentially, in favour of the second code in some cases –when the developer knows the environment the application is running– can only be advocated in the special case that the program has set up a private environment for itself (and other instances of the same program).

Even in that case, this is a bad practice and can lead to long useless debugging. For example, the fact we set the permissions for a directory should not leave us with the impression permissions are set appropriately for our purposes. A parent directory could be mounted with other permissions. In general, a program should always work correctly and the programmer should not expect one specific environment.


回答 12

Python3中os.makedirs支持设置exist_ok。默认设置为False,这意味着OSError如果目标目录已存在,将引发。通过设置exist_okTrueOSError(目录存在)将被忽略,并且不会创建目录。

os.makedirs(path,exist_ok=True)

Python2中os.makedirs不支持设置exist_ok。您可以在heikki-toivonen的答案中使用该方法:

import os
import errno

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

In Python3, os.makedirs supports setting exist_ok. The default setting is False, which means an OSError will be raised if the target directory already exists. By setting exist_ok to True, OSError (directory exists) will be ignored and the directory will not be created.

os.makedirs(path,exist_ok=True)

In Python2, os.makedirs doesn’t support setting exist_ok. You can use the approach in heikki-toivonen’s answer:

import os
import errno

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

回答 13

对于单线解决方案,可以使用IPython.utils.path.ensure_dir_exists()

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

文档中确保目录存在。如果不存在,请尝试创建它,并在其他进程正在这样做的情况下防止出现竞争情况。

For a one-liner solution, you can use IPython.utils.path.ensure_dir_exists():

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

From the documentation: Ensure that a directory exists. If it doesn’t exist, try to create it and protect against a race condition if another process is doing the same.


回答 14

您可以使用 mkpath

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

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

请注意,它也会创建祖先目录。

它适用于Python 2和3。

You can use mkpath

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

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

Note that it will create the ancestor directories as well.

It works for Python 2 and 3.


回答 15

我使用os.path.exists()是一个Python 3脚本,可用于检查目录是否存在,如果目录不存在则创建一个,如果目录存在则将其删除(如果需要)。

它提示用户输入目录,并且可以轻松修改。

I use os.path.exists(), here is a Python 3 script that can be used to check if a directory exists, create one if it does not exist, and delete it if it does exist (if desired).

It prompts users for input of the directory and can be easily modified.


回答 16

您可以os.listdir为此使用:

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

You can use os.listdir for this:

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

回答 17

我找到了这个问题,起初我为自己遇到的一些失败和错误感到困惑。我正在使用Python 3(Arch Linux x86_64系统上的Anaconda虚拟环境中的v.3.5)。

考虑以下目录结构:

└── 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

I found this Q/A and I was initially puzzled by some of the failures and errors I was getting. I am working in Python 3 (v.3.5 in an Anaconda virtual environment on an Arch Linux x86_64 system).

Consider this directory structure:

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

Here are my experiments/notes, which clarifies things:

# ----------------------------------------------------------------------------
# [1] https://stackoverflow.com/questions/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
# ----------------------------------------------------------------------------

Conclusion: in my opinion, “Method 2” is more robust.

[1] How can I create a directory if it does not exist?

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


回答 18

我看到了Heikki ToivonenABB的答案,并想到了这种变化。

import os
import errno

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

I saw Heikki Toivonen and A-B-B‘s answers and thought of this variation.

import os
import errno

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

回答 19

使用此命令检查并创建目录

 if not os.path.isdir(test_img_dir):
     os.mkdir(test_img_dir)

Use this command check and create dir

 if not os.path.isdir(test_img_dir):
     os.mkdir(test_img_dir)

回答 20

如果在支持mkdir-p选项命令的计算机上运行,​​为什么不使用子流程模块 ?适用于python 2.7和python 3.6

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

在大多数系统上都可以做到。

在可移植性无关紧要的情况下(例如,使用docker),解决方案只需2行。您也不必添加逻辑来检查目录是否存在。最后,重新运行很安全,没有任何副作用

如果您需要错误处理:

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

Why not use subprocess module if running on a machine that supports command mkdir with -p option ? Works on python 2.7 and python 3.6

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

Should do the trick on most systems.

In situations where portability doesn’t matter (ex, using docker) the solution is a clean 2 lines. You also don’t have to add logic to check if directories exist or not. Finally, it is safe to re-run without any side effects

If you need error handling:

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

回答 21

如果考虑以下因素:

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

表示目录(路径)存在,并且是目录。所以对我来说,这种方式满足了我的需求。因此,我可以确保它是文件夹(不是文件)并且存在。

If you consider the following:

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

means a directory (path) exists AND is a directory. So for me this way does what I need. So I can make sure it is folder (not a file) and exists.


回答 22

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')

Call the function create_dir() at the entry point of your program/project.

import os

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

create_dir('Project directory')

回答 23

您必须在创建目录之前设置完整路径:

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)

这对我有用,希望对您也一样

You have to set the full path before creating the directory:

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)

This works for me and hopefully, it will works for you as well


回答 24

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

您的代码在哪里使用(touch)命令

这将检查文件是否存在,如果不存在则将创建它。

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

Where your code here is use the (touch) command

This will check if the file is there if it is not then it will create it.