关于python:os.path.splitext相对于 .split好处

Benefits of os.path.splitext over regular .split?

在另一个问题中,投票清楚地表明,与简单的.split('.')[-1]字符串操作相比,os.path.splitext函数更受欢迎。有没有人有时间解释这到底是为什么?是更快,还是更准确,还是什么?我愿意接受它有更好的地方,但我不能马上看到它可能是什么。至少在简单的情况下,导入一个完整的模块来完成这项工作可能会有点过分?

编辑:操作系统的特殊性是一个巨大的胜利,这并不是显而易见的;但即使我也应该看到"如果没有点怎么办"的情况!感谢大家对图书馆使用的总体评价。


嗯,对于不同的操作系统有不同的实现。这意味着,如果在Mac上提取文件扩展名的逻辑与在Linux上提取文件扩展名的逻辑不同,那么这些东西将处理这种区别。我不知道有什么区别,所以可能没有。

编辑:@brian评论说,像/directory.ext/file这样的例子当然不适用于一个简单的.split('.')调用,而且您必须知道两个目录都可以使用扩展,而且在某些操作系统上,正斜杠是一个有效的目录分隔符。

这只强调使用一个库程序,除非你有充分的理由不回答我的部分问题。

谢谢你,布瑞恩。

此外,如果一个文件没有扩展名,那么就必须构建逻辑来处理这种情况。如果你要分割的是以反斜杠结尾的目录名呢?没有文件名或扩展名。

规则应该是,除非您有特定的理由不使用执行所需操作的库函数,否则请使用它。这将避免您必须维护和错误修复代码,而其他人拥有完美的解决方案。


splitext将正确处理文件没有扩展名的情况,并返回空字符串。.split将返回文件名。


splitext()对''进行反向搜索,并在找到扩展部分后立即返回。split('.')将对所有"."字符进行正向搜索,因此几乎总是较慢。换句话说,与split()不同,splitext()是专门为返回扩展名而编写的。

(如果要检查实现,请参见Python源代码中的posixpath.py)。


存在不使用"."作为扩展分隔符的操作系统。

(值得注意的是,按照约定,RISC OS使用"/",因为"."在那里用作路径分隔符。)


  • 正确的工作工具
  • 已经作为python标准库的一部分进行了彻底的调试和测试-没有错误引入您的手动滚动版本(例如,如果没有扩展名,或者文件是一个隐藏在unix上的文件,比如".bashrc",或者有多个扩展名呢?)
  • 为此目的而设计的函数对于传递的文件名具有有用的返回值(basename,ext),这在某些情况下可能更有用,而不必手动拆分路径(同样,在计算basename-ext时,边缘情况可能是一个问题)。
  • 担心导入模块的唯一原因是担心开销——在大多数情况下,这不太可能是一个问题,如果它是那么紧的话,那么在Python中的其他开销很可能是一个更大的问题。


    与随意拆分字符串相比,获取文件扩展名的明确定义和文档化方法总是首选的,因为由于各种原因,该方法更脆弱。

    编辑:这不是特定语言。


    第一个也是最明显的区别是,当没有扩展名时,split调用中没有默认逻辑。

    这也可以通过一个regex来实现,以便让它表现为一个没有额外include但仍然返回空字符串(如果扩展不存在的话)的1行程序。

    此外,路径库可以为文件夹具有不同分隔符的路径处理不同的上下文。


    我不确定python是否已经移植到了vms平台上,但假设它已经移植了(*):

    • 文件名的格式通常为:$device dir subdir$filename.$type;$version(**)

    我希望您认识到,使用仅受您所接触的系统影响的窄范围方法并不是长期代码可维护性的最佳选择,而且这种做法对于在大型软件项目中混合和匹配不同的软件组件尤其不利。

    本质上,在后一种情况下,成功概率(可靠性)类似于

    R(t)=1-(1-Ri)^n

    现在您可以看到糟糕/不完整的软件实现如何导致有缺陷的程序。更广泛地说,正是由于这样的错误,移植软件很困难。

    (*)嗯,谷歌很快就发现了:https://www.vmspython.org(**)看看这里的雷吉克斯战争!https://stackoverflow.com/a/4465456/1574494


    1)简单拆分(".")[-1]对于路径C:foo.barmakefile无法正常工作,因此需要首先使用os.path.basename()提取basename,即使在这种情况下,也无法正确拆分没有扩展名的文件。os.path.splitext在引擎盖下执行此操作。

    2)尽管os.path.splitext是跨平台解决方案,但它并不理想。让我们看看带前导点的特殊文件,例如.cvsignore,.bzignore,.hignore(它们在某些VCS中作为特殊文件非常流行)。os.path.splitext将返回整个文件名作为扩展名,尽管它似乎不适合我。因为在这种情况下,没有扩展名的名称是空字符串。尽管这是Python标准库的预期行为,但它可能不是用户真正想要的。


    os.path.splitext除了是标准的,因此保证可用外:

    处理边缘情况-就像丢失扩展名一样。提供保证-除了正确返回扩展名(如果存在),它还保证rootext始终返回完整路径。是跨平台的——在python源代码中,实际上有三个不同版本的os.path,它们是根据python认为您所处的操作系统来调用的。更具可读性-考虑到您的版本要求用户知道数组可以用负数索引。

    顺便说一句,不应该再快了。


    在提供此解决方案的答案的注释中:

    "If the file has no extension this incorrectly returns the file name instead of an empty string."

    不是每个文件都有扩展名。